|
Video Processing Framework
|
00001 #ifndef NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 00002 #define NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 00003 00004 #if !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 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