#ifndef NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODEREADIMPL_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 namespace YAML { // implementation for Node::Read // (the goal is to call ConvertScalar if we can, and fall back to operator >> if not) // thanks to litb from stackoverflow.com // http://stackoverflow.com/questions/1386183/how-to-call-a-templated-function-if-it-exists-and-something-else-otherwise/1386390#1386390 // Note: this doesn't work on gcc 3.2, but does on gcc 3.4 and above. I'm not sure about 3.3. #if __GNUC__ && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 3)) // trick doesn't work? Just fall back to ConvertScalar. // This means that we can't use any user-defined types as keys in a map template inline bool Node::Read(T& value) const { return ConvertScalar(*this, value); } #else // usual case: the trick! template struct read_impl; // ConvertScalar available template<> struct read_impl { template static bool read(const Node& node, T& value) { return ConvertScalar(node, value); } }; // ConvertScalar not available template<> struct read_impl { template static bool read(const Node& node, T& value) { try { node >> value; } catch(const Exception&) { return false; } return true; } }; namespace fallback { // sizeof > 1 struct flag { char c[2]; }; flag Convert(...); int operator,(flag, flag); template char operator,(flag, T const&); char operator,(int, flag); int operator,(char, flag); } template inline bool Node::Read(T& value) const { using namespace fallback; return read_impl::read(*this, value); } #endif // done with trick // the main conversion function template inline bool ConvertScalar(const Node& node, T& value) { std::string scalar; if(!node.GetScalar(scalar)) return false; return Convert(scalar, value); } } #endif // NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66