#ifndef __YAMLPROVIDERYAMLEXTENSIONS_H__ #define __YAMLPROVIDERYAMLEXTENSIONS_H__ #include #include #include #include #include namespace YAML { template< typename T > static void operator >> (const Node & nd, T & target) { if (!nd) throw YAML::TypedKeyNotFound< std::string > (nd.Mark(), "This key is not defined here"); else target = nd.as(); } template< typename T > void operator >> (const Node & nd, mars::Range< T > & rng) { if (nd.Type() == NodeType::Sequence) { nd[0] >> rng.minimum; nd[1] >> rng.maximum; rng.update(); } else { nd >> rng.minimum; nd >> rng.maximum; rng.update(); } } template< typename T > void operator >> (const Node & nd, mars::RangeX< T > & rng) { if (nd.Type() == NodeType::Sequence) { nd[0] >> rng.minimum; nd[1] >> rng.maximum; rng.update(); } else { nd >> rng.minimum; nd >> rng.maximum; rng.update(); } } template static void operator >> (const Node & nd, L & l) { E e; if (nd.Type() == NodeType::Sequence) { for (const_iterator it = nd.begin(); it != nd.end(); ++it) { *it >> e; l.push_back(e); } } else { nd >> e; l.push_back(e); } } template< typename E > class StringMapSchema { private: typedef std::map< std::string, E > MapType; MapType _map; public: StringMapSchema (const char * szFirst, /*const E & eFirst, */...) { va_list vl; const char * szIdent = szFirst; va_start(vl, szFirst); while(szIdent != NULL) { _map[szIdent] = static_cast< E > (va_arg(vl, int)); szIdent = va_arg(vl, const char *); } va_end(vl); } bool setValue (E & e, const std::string & s) const { typename MapType::const_iterator i = _map.find(s); if (i != _map.end()) { e = i->second; return true; } return false; } }; template< typename E > class MappedValue { private: E & _e; const StringMapSchema< E > & _schema; public: MappedValue (E & e, const StringMapSchema< E > & schema) : _e(e), _schema(schema) {} inline bool operator << (const std::string & s) { return _schema.setValue(_e, s); } }; template< typename E > class MappedRange { private: mars::Range< E > & _rng; const StringMapSchema< E > & _schema; public: MappedRange (mars::Range< E > & rng, const StringMapSchema< E > & schema) : _rng(rng), _schema(schema) {} bool operator << (const std::string & s) { E e; if (_schema.setValue(e, s)) { _rng.minimum = _rng.maximum = e; _rng.update(); return true; } return false; } bool setRange (const std::string & sMin, const std::string & sMax) { E eMin, eMax; if (_schema.setValue(eMin, sMin) && _schema.setValue(eMax, sMax)) { _rng.minimum = eMin; _rng.maximum = eMax; _rng.update(); return true; } return false; } }; template< typename E > void operator >> (const Node & nd, MappedValue< E > mapped) { std::string s; nd >> s; if (!(mapped << s)) throw RepresentationException(nd.Mark(), "Unknown identifier for mapped value: " + s); } template< typename E > void operator >> (const Node & nd, MappedRange< E > mapped) { if (nd.Type() == NodeType::Sequence) { std::string sMin, sMax; nd[0] >> sMin; nd[1] >> sMax; if (!mapped.setRange(sMin, sMax)) throw RepresentationException(nd.Mark(), "Unknown identifier(s) for mapped range: " + sMin + "/" + sMax); } else { std::string s; nd >> s; if (!(mapped << s)) throw RepresentationException(nd.Mark(), "Unknown identifier for mapped range: " + s); } } } #endif