#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #pragma once #endif #include "yaml-cpp/binary.h" #include "yaml-cpp/node/node.h" #include "yaml-cpp/node/iterator.h" #include "yaml-cpp/null.h" #include #include #include #include #include namespace YAML { namespace conversion { inline bool IsInfinity(const std::string& input) { return input == ".inf" || input == ".Inf" || input == ".INF" || input == "+.inf" || input == "+.Inf" || input == "+.INF"; } inline bool IsNegativeInfinity(const std::string& input) { return input == "-.inf" || input == "-.Inf" || input == "-.INF"; } inline bool IsNaN(const std::string& input) { return input == ".nan" || input == ".NaN" || input == ".NAN"; } } // std::string template<> struct convert { static Node encode(const std::string& rhs) { return Node(rhs); } static bool decode(const Node& node, std::string& rhs) { if(!node.IsScalar()) return false; rhs = node.Scalar(); return true; } }; template<> struct convert<_Null> { static Node encode(const _Null& /* rhs */) { return Node(); } static bool decode(const Node& node, _Null& /* rhs */) { return node.IsNull(); } }; #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op)\ template<>\ struct convert {\ static Node encode(const type& rhs) {\ std::stringstream stream;\ stream << rhs;\ return Node(stream.str());\ }\ \ static bool decode(const Node& node, type& rhs) {\ if(node.Type() != NodeType::Scalar)\ return false;\ const std::string& input = node.Scalar();\ std::stringstream stream(input);\ stream.unsetf(std::ios::dec);\ if((stream >> rhs) && (stream >> std::ws).eof())\ return true;\ if(std::numeric_limits::has_infinity) {\ if(conversion::IsInfinity(input)) {\ rhs = std::numeric_limits::infinity();\ return true;\ } else if(conversion::IsNegativeInfinity(input)) {\ rhs = negative_op std::numeric_limits::infinity();\ return true;\ }\ }\ \ if(std::numeric_limits::has_quiet_NaN && conversion::IsNaN(input)) {\ rhs = std::numeric_limits::quiet_NaN();\ return true;\ }\ \ return false;\ }\ } #define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type)\ YAML_DEFINE_CONVERT_STREAMABLE(type, -) #define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type)\ YAML_DEFINE_CONVERT_STREAMABLE(type, +) YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double); #undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED #undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED #undef YAML_DEFINE_CONVERT_STREAMABLE // bool template<> struct convert { static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } static bool decode(const Node& node, bool& rhs); }; // std::map template struct convert > { static Node encode(const std::map& rhs) { Node node(NodeType::Map); for(typename std::map::const_iterator it=rhs.begin();it!=rhs.end();++it) node.force_insert(it->first, it->second); return node; } static bool decode(const Node& node, std::map& rhs) { if(!node.IsMap()) return false; rhs.clear(); for(const_iterator it=node.begin();it!=node.end();++it) #if defined(__GNUC__) && __GNUC__ < 4 //workaround for GCC 3: rhs[it->first.template as()] = it->second.template as(); #else rhs[it->first.as()] = it->second.as(); #endif return true; } }; // std::vector template struct convert > { static Node encode(const std::vector& rhs) { Node node(NodeType::Sequence); for(typename std::vector::const_iterator it=rhs.begin();it!=rhs.end();++it) node.push_back(*it); return node; } static bool decode(const Node& node, std::vector& rhs) { if(!node.IsSequence()) return false; rhs.clear(); for(const_iterator it=node.begin();it!=node.end();++it) #if defined(__GNUC__) && __GNUC__ < 4 //workaround for GCC 3: rhs.push_back(it->template as()); #else rhs.push_back(it->as()); #endif return true; } }; // std::list template struct convert > { static Node encode(const std::list& rhs) { Node node(NodeType::Sequence); for(typename std::list::const_iterator it=rhs.begin();it!=rhs.end();++it) node.push_back(*it); return node; } static bool decode(const Node& node, std::list& rhs) { if(!node.IsSequence()) return false; rhs.clear(); for(const_iterator it=node.begin();it!=node.end();++it) #if defined(__GNUC__) && __GNUC__ < 4 //workaround for GCC 3: rhs.push_back(it->template as()); #else rhs.push_back(it->as()); #endif return true; } }; // binary template<> struct convert { static Node encode(const Binary& rhs) { return Node(EncodeBase64(rhs.data(), rhs.size())); } static bool decode(const Node& node, Binary& rhs) { if(!node.IsScalar()) return false; std::vector data = DecodeBase64(node.Scalar()); if(data.empty() && !node.Scalar().empty()) return false; rhs.swap(data); return true; } }; } #endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66