Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:55:05

0001 #ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0002 #define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
0003 
0004 #if defined(_MSC_VER) ||                                            \
0005     (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
0006      (__GNUC__ >= 4))  // GCC supports "pragma once" correctly since 3.4
0007 #pragma once
0008 #endif
0009 
0010 #include <array>
0011 #include <cmath>
0012 #include <limits>
0013 #include <list>
0014 #include <map>
0015 #include <unordered_map>
0016 #include <sstream>
0017 #include <type_traits>
0018 #include <valarray>
0019 #include <vector>
0020 
0021 #if __cplusplus >= 201703L
0022 #include <string_view>
0023 #endif
0024 
0025 #include "yaml-cpp/binary.h"
0026 #include "yaml-cpp/node/impl.h"
0027 #include "yaml-cpp/node/iterator.h"
0028 #include "yaml-cpp/node/node.h"
0029 #include "yaml-cpp/node/type.h"
0030 #include "yaml-cpp/null.h"
0031 
0032 
0033 namespace YAML {
0034 class Binary;
0035 struct _Null;
0036 template <typename T>
0037 struct convert;
0038 }  // namespace YAML
0039 
0040 namespace YAML {
0041 namespace conversion {
0042 inline bool IsInfinity(const std::string& input) {
0043   return input == ".inf" || input == ".Inf" || input == ".INF" ||
0044          input == "+.inf" || input == "+.Inf" || input == "+.INF";
0045 }
0046 
0047 inline bool IsNegativeInfinity(const std::string& input) {
0048   return input == "-.inf" || input == "-.Inf" || input == "-.INF";
0049 }
0050 
0051 inline bool IsNaN(const std::string& input) {
0052   return input == ".nan" || input == ".NaN" || input == ".NAN";
0053 }
0054 }
0055 
0056 // Node
0057 template <>
0058 struct convert<Node> {
0059   static Node encode(const Node& rhs) { return rhs; }
0060 
0061   static bool decode(const Node& node, Node& rhs) {
0062     rhs.reset(node);
0063     return true;
0064   }
0065 };
0066 
0067 // std::string
0068 template <>
0069 struct convert<std::string> {
0070   static Node encode(const std::string& rhs) { return Node(rhs); }
0071 
0072   static bool decode(const Node& node, std::string& rhs) {
0073     if (!node.IsScalar())
0074       return false;
0075     rhs = node.Scalar();
0076     return true;
0077   }
0078 };
0079 
0080 // C-strings can only be encoded
0081 template <>
0082 struct convert<const char*> {
0083   static Node encode(const char* rhs) { return Node(rhs); }
0084 };
0085 
0086 template <>
0087 struct convert<char*> {
0088   static Node encode(const char* rhs) { return Node(rhs); }
0089 };
0090 
0091 template <std::size_t N>
0092 struct convert<char[N]> {
0093   static Node encode(const char* rhs) { return Node(rhs); }
0094 };
0095 
0096 #if __cplusplus >= 201703L
0097 template <>
0098 struct convert<std::string_view> {
0099   static Node encode(std::string_view rhs) { return Node(std::string(rhs)); }
0100 
0101   static bool decode(const Node& node, std::string_view& rhs) {
0102     if (!node.IsScalar())
0103       return false;
0104     rhs = node.Scalar();
0105     return true;
0106   }
0107 };
0108 #endif
0109 
0110 template <>
0111 struct convert<_Null> {
0112   static Node encode(const _Null& /* rhs */) { return Node(); }
0113 
0114   static bool decode(const Node& node, _Null& /* rhs */) {
0115     return node.IsNull();
0116   }
0117 };
0118 
0119 namespace conversion {
0120 template <typename T>
0121 typename std::enable_if< std::is_floating_point<T>::value, void>::type
0122 inner_encode(const T& rhs, std::stringstream& stream){
0123   if (std::isnan(rhs)) {
0124     stream << ".nan";
0125   } else if (std::isinf(rhs)) {
0126     if (std::signbit(rhs)) {
0127       stream << "-.inf";
0128     } else {
0129       stream << ".inf";
0130     }
0131   } else {
0132     stream << rhs;
0133   }
0134 }
0135 
0136 template <typename T>
0137 typename std::enable_if<!std::is_floating_point<T>::value, void>::type
0138 inner_encode(const T& rhs, std::stringstream& stream){
0139   stream << rhs;
0140 }
0141 
0142 template <typename T>
0143 typename std::enable_if<(std::is_same<T, unsigned char>::value ||
0144                          std::is_same<T, signed char>::value), bool>::type
0145 ConvertStreamTo(std::stringstream& stream, T& rhs) {
0146   int num;
0147   if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) {
0148     if (num >= (std::numeric_limits<T>::min)() &&
0149         num <= (std::numeric_limits<T>::max)()) {
0150       rhs = static_cast<T>(num);
0151       return true;
0152     }
0153   }
0154   return false;
0155 }
0156 
0157 template <typename T>
0158 typename std::enable_if<!(std::is_same<T, unsigned char>::value ||
0159                           std::is_same<T, signed char>::value), bool>::type
0160 ConvertStreamTo(std::stringstream& stream, T& rhs) {
0161   if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) {
0162     return true;
0163   }
0164   return false;
0165 }
0166 }
0167 
0168 #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op)                  \
0169   template <>                                                              \
0170   struct convert<type> {                                                   \
0171                                                                            \
0172     static Node encode(const type& rhs) {                                  \
0173       std::stringstream stream;                                            \
0174       stream.precision(std::numeric_limits<type>::max_digits10);           \
0175       conversion::inner_encode(rhs, stream);                               \
0176       return Node(stream.str());                                           \
0177     }                                                                      \
0178                                                                            \
0179     static bool decode(const Node& node, type& rhs) {                      \
0180       if (node.Type() != NodeType::Scalar) {                               \
0181         return false;                                                      \
0182       }                                                                    \
0183       const std::string& input = node.Scalar();                            \
0184       std::stringstream stream(input);                                     \
0185       stream.unsetf(std::ios::dec);                                        \
0186       if ((stream.peek() == '-') && std::is_unsigned<type>::value) {       \
0187         return false;                                                      \
0188       }                                                                    \
0189       if (conversion::ConvertStreamTo(stream, rhs)) {                      \
0190         return true;                                                       \
0191       }                                                                    \
0192       if (std::numeric_limits<type>::has_infinity) {                       \
0193         if (conversion::IsInfinity(input)) {                               \
0194           rhs = std::numeric_limits<type>::infinity();                     \
0195           return true;                                                     \
0196         } else if (conversion::IsNegativeInfinity(input)) {                \
0197           rhs = negative_op std::numeric_limits<type>::infinity();         \
0198           return true;                                                     \
0199         }                                                                  \
0200       }                                                                    \
0201                                                                            \
0202       if (std::numeric_limits<type>::has_quiet_NaN) {                      \
0203         if (conversion::IsNaN(input)) {                                    \
0204           rhs = std::numeric_limits<type>::quiet_NaN();                    \
0205           return true;                                                     \
0206         }                                                                  \
0207       }                                                                    \
0208                                                                            \
0209       return false;                                                        \
0210     }                                                                      \
0211   }
0212 
0213 #define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
0214   YAML_DEFINE_CONVERT_STREAMABLE(type, -)
0215 
0216 #define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \
0217   YAML_DEFINE_CONVERT_STREAMABLE(type, +)
0218 
0219 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
0220 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
0221 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
0222 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
0223 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
0224 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
0225 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
0226 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
0227 
0228 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
0229 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(signed char);
0230 YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
0231 
0232 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
0233 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
0234 YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
0235 
0236 #undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
0237 #undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
0238 #undef YAML_DEFINE_CONVERT_STREAMABLE
0239 
0240 // bool
0241 template <>
0242 struct convert<bool> {
0243   static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); }
0244 
0245   YAML_CPP_API static bool decode(const Node& node, bool& rhs);
0246 };
0247 
0248 // std::map
0249 template <typename K, typename V, typename C, typename A>
0250 struct convert<std::map<K, V, C, A>> {
0251   static Node encode(const std::map<K, V, C, A>& rhs) {
0252     Node node(NodeType::Map);
0253     for (const auto& element : rhs)
0254       node.force_insert(element.first, element.second);
0255     return node;
0256   }
0257 
0258   static bool decode(const Node& node, std::map<K, V, C, A>& rhs) {
0259     if (!node.IsMap())
0260       return false;
0261 
0262     rhs.clear();
0263     for (const auto& element : node)
0264 #if defined(__GNUC__) && __GNUC__ < 4
0265       // workaround for GCC 3:
0266       rhs[element.first.template as<K>()] = element.second.template as<V>();
0267 #else
0268       rhs[element.first.as<K>()] = element.second.as<V>();
0269 #endif
0270     return true;
0271   }
0272 };
0273 
0274 // std::unordered_map
0275 template <typename K, typename V, typename H, typename P, typename A>
0276 struct convert<std::unordered_map<K, V, H, P, A>> {
0277   static Node encode(const std::unordered_map<K, V, H, P, A>& rhs) {
0278     Node node(NodeType::Map);
0279     for (const auto& element : rhs)
0280       node.force_insert(element.first, element.second);
0281     return node;
0282   }
0283 
0284   static bool decode(const Node& node, std::unordered_map<K, V, H, P, A>& rhs) {
0285     if (!node.IsMap())
0286       return false;
0287 
0288     rhs.clear();
0289     for (const auto& element : node)
0290 #if defined(__GNUC__) && __GNUC__ < 4
0291       // workaround for GCC 3:
0292       rhs[element.first.template as<K>()] = element.second.template as<V>();
0293 #else
0294       rhs[element.first.as<K>()] = element.second.as<V>();
0295 #endif
0296     return true;
0297   }
0298 };
0299 
0300 // std::vector
0301 template <typename T, typename A>
0302 struct convert<std::vector<T, A>> {
0303   static Node encode(const std::vector<T, A>& rhs) {
0304     Node node(NodeType::Sequence);
0305     for (const auto& element : rhs)
0306       node.push_back(element);
0307     return node;
0308   }
0309 
0310   static bool decode(const Node& node, std::vector<T, A>& rhs) {
0311     if (!node.IsSequence())
0312       return false;
0313 
0314     rhs.clear();
0315     for (const auto& element : node)
0316 #if defined(__GNUC__) && __GNUC__ < 4
0317       // workaround for GCC 3:
0318       rhs.push_back(element.template as<T>());
0319 #else
0320       rhs.push_back(element.as<T>());
0321 #endif
0322     return true;
0323   }
0324 };
0325 
0326 // std::list
0327 template <typename T, typename A>
0328 struct convert<std::list<T,A>> {
0329   static Node encode(const std::list<T,A>& rhs) {
0330     Node node(NodeType::Sequence);
0331     for (const auto& element : rhs)
0332       node.push_back(element);
0333     return node;
0334   }
0335 
0336   static bool decode(const Node& node, std::list<T,A>& rhs) {
0337     if (!node.IsSequence())
0338       return false;
0339 
0340     rhs.clear();
0341     for (const auto& element : node)
0342 #if defined(__GNUC__) && __GNUC__ < 4
0343       // workaround for GCC 3:
0344       rhs.push_back(element.template as<T>());
0345 #else
0346       rhs.push_back(element.as<T>());
0347 #endif
0348     return true;
0349   }
0350 };
0351 
0352 // std::array
0353 template <typename T, std::size_t N>
0354 struct convert<std::array<T, N>> {
0355   static Node encode(const std::array<T, N>& rhs) {
0356     Node node(NodeType::Sequence);
0357     for (const auto& element : rhs) {
0358       node.push_back(element);
0359     }
0360     return node;
0361   }
0362 
0363   static bool decode(const Node& node, std::array<T, N>& rhs) {
0364     if (!isNodeValid(node)) {
0365       return false;
0366     }
0367 
0368     for (auto i = 0u; i < node.size(); ++i) {
0369 #if defined(__GNUC__) && __GNUC__ < 4
0370       // workaround for GCC 3:
0371       rhs[i] = node[i].template as<T>();
0372 #else
0373       rhs[i] = node[i].as<T>();
0374 #endif
0375     }
0376     return true;
0377   }
0378 
0379  private:
0380   static bool isNodeValid(const Node& node) {
0381     return node.IsSequence() && node.size() == N;
0382   }
0383 };
0384 
0385 
0386 // std::valarray
0387 template <typename T>
0388 struct convert<std::valarray<T>> {
0389   static Node encode(const std::valarray<T>& rhs) {
0390     Node node(NodeType::Sequence);
0391     for (const auto& element : rhs) {
0392       node.push_back(element);
0393     }
0394     return node;
0395   }
0396 
0397   static bool decode(const Node& node, std::valarray<T>& rhs) {
0398     if (!node.IsSequence()) {
0399       return false;
0400     }
0401 
0402     rhs.resize(node.size());
0403     for (auto i = 0u; i < node.size(); ++i) {
0404 #if defined(__GNUC__) && __GNUC__ < 4
0405       // workaround for GCC 3:
0406       rhs[i] = node[i].template as<T>();
0407 #else
0408       rhs[i] = node[i].as<T>();
0409 #endif
0410     }
0411     return true;
0412   }
0413 };
0414 
0415 
0416 // std::pair
0417 template <typename T, typename U>
0418 struct convert<std::pair<T, U>> {
0419   static Node encode(const std::pair<T, U>& rhs) {
0420     Node node(NodeType::Sequence);
0421     node.push_back(rhs.first);
0422     node.push_back(rhs.second);
0423     return node;
0424   }
0425 
0426   static bool decode(const Node& node, std::pair<T, U>& rhs) {
0427     if (!node.IsSequence())
0428       return false;
0429     if (node.size() != 2)
0430       return false;
0431 
0432 #if defined(__GNUC__) && __GNUC__ < 4
0433     // workaround for GCC 3:
0434     rhs.first = node[0].template as<T>();
0435 #else
0436     rhs.first = node[0].as<T>();
0437 #endif
0438 #if defined(__GNUC__) && __GNUC__ < 4
0439     // workaround for GCC 3:
0440     rhs.second = node[1].template as<U>();
0441 #else
0442     rhs.second = node[1].as<U>();
0443 #endif
0444     return true;
0445   }
0446 };
0447 
0448 // binary
0449 template <>
0450 struct convert<Binary> {
0451   static Node encode(const Binary& rhs) {
0452     return Node(EncodeBase64(rhs.data(), rhs.size()));
0453   }
0454 
0455   static bool decode(const Node& node, Binary& rhs) {
0456     if (!node.IsScalar())
0457       return false;
0458 
0459     std::vector<unsigned char> data = DecodeBase64(node.Scalar());
0460     if (data.empty() && !node.Scalar().empty())
0461       return false;
0462 
0463     rhs.swap(data);
0464     return true;
0465   }
0466 };
0467 }
0468 
0469 #endif  // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66