1 #ifndef NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
4 #if !defined(__GNUC__) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4) // GCC supports "pragma once" correctly since 3.4
11 // implementation for Node::Read
12 // (the goal is to call ConvertScalar if we can, and fall back to operator >> if not)
13 // thanks to litb from stackoverflow.com
14 // http://stackoverflow.com/questions/1386183/how-to-call-a-templated-function-if-it-exists-and-something-else-otherwise/1386390#1386390
16 // Note: this doesn't work on gcc 3.2, but does on gcc 3.4 and above. I'm not sure about 3.3.
18 #if __GNUC__ && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 3))
19 // trick doesn't work? Just fall back to ConvertScalar.
20 // This means that we can't use any user-defined types as keys in a map
22 inline bool Node::Read(T
& value
) const {
23 return ConvertScalar(*this, value
);
26 // usual case: the trick!
30 // ConvertScalar available
32 struct read_impl
<true> {
34 static bool read(const Node
& node
, T
& value
) {
35 return ConvertScalar(node
, value
);
39 // ConvertScalar not available
41 struct read_impl
<false> {
43 static bool read(const Node
& node
, T
& value
) {
46 } catch(const Exception
&) {
55 struct flag
{ char c
[2]; };
58 int operator,(flag
, flag
);
61 char operator,(flag
, T
const&);
63 char operator,(int, flag
);
64 int operator,(char, flag
);
68 inline bool Node::Read(T
& value
) const {
69 using namespace fallback
;
71 return read_impl
<sizeof (fallback::flag(), Convert(std::string(), value
), fallback::flag()) != 1>::read(*this, value
);
73 #endif // done with trick
75 // the main conversion function
77 inline bool ConvertScalar(const Node
& node
, T
& value
) {
79 if(!node
.GetScalar(scalar
))
82 return Convert(scalar
, value
);
86 #endif // NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66