nodereadimpl.h
Go to the documentation of this file.
00001 #ifndef NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
00002 #define NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
00003 
00004 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
00005 #pragma once
00006 #endif
00007 
00008 
00009 namespace YAML_PM
00010 {
00011         // implementation for Node::Read
00012         // (the goal is to call ConvertScalar if we can, and fall back to operator >> if not)
00013         // thanks to litb from stackoverflow.com
00014         // http://stackoverflow.com/questions/1386183/how-to-call-a-templated-function-if-it-exists-and-something-else-otherwise/1386390#1386390
00015 
00016         // Note: this doesn't work on gcc 3.2, but does on gcc 3.4 and above. I'm not sure about 3.3.
00017         
00018 #if __GNUC__ && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 3))
00019         // trick doesn't work? Just fall back to ConvertScalar.
00020         // This means that we can't use any user-defined types as keys in a map
00021         template <typename T>
00022         inline bool Node::Read(T& value) const {
00023                 return ConvertScalar(*this, value);
00024         }
00025 #else
00026         // usual case: the trick!
00027         template<bool>
00028         struct read_impl;
00029         
00030         // ConvertScalar available
00031         template<>
00032         struct read_impl<true> {
00033                 template<typename T>
00034                 static bool read(const Node& node, T& value) {
00035                         return ConvertScalar(node, value);
00036                 }
00037         };
00038 
00039         // ConvertScalar not available
00040         template<>
00041         struct read_impl<false> {
00042                 template<typename T>
00043                 static bool read(const Node& node, T& value) {
00044                         try {
00045                                 node >> value;
00046                         } catch(const Exception&) {
00047                                 return false;
00048                         }
00049                         return true;
00050                 }
00051         };
00052         
00053         namespace fallback {
00054                 // sizeof > 1
00055                 struct flag { char c[2]; };
00056                 flag Convert(...);
00057                 
00058                 int operator,(flag, flag);
00059                 
00060                 template<typename T>
00061                 char operator,(flag, T const&);
00062                 
00063                 char operator,(int, flag);
00064                 int operator,(char, flag);
00065         }
00066 
00067         template <typename T>
00068         inline bool Node::Read(T& value) const {
00069                 using namespace fallback;
00070 
00071                 return read_impl<sizeof (fallback::flag(), Convert(std::string(), value), fallback::flag()) != 1>::read(*this, value);
00072         }
00073 #endif // done with trick
00074         
00075         // the main conversion function
00076         template <typename T>
00077         inline bool ConvertScalar(const Node& node, T& value) {
00078                 std::string scalar;
00079                 if(!node.GetScalar(scalar))
00080                         return false;
00081                 
00082                 return Convert(scalar, value);
00083         }
00084 }
00085 
00086 #endif // NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66


upstream_src
Author(s):
autogenerated on Mon Oct 6 2014 10:27:42