79 lines
1.9 KiB
C++
79 lines
1.9 KiB
C++
#pragma once
|
|
|
|
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 <typename T>
|
|
inline bool Node::Read(T& value) const {
|
|
return ConvertScalar(*this, value);
|
|
}
|
|
#else
|
|
// usual case: the trick!
|
|
template<bool>
|
|
struct read_impl;
|
|
|
|
// ConvertScalar available
|
|
template<>
|
|
struct read_impl<true> {
|
|
template<typename T>
|
|
static bool read(const Node& node, T& value) {
|
|
return ConvertScalar(node, value);
|
|
}
|
|
};
|
|
|
|
// ConvertScalar not available
|
|
template<>
|
|
struct read_impl<false> {
|
|
template<typename T>
|
|
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<typename T>
|
|
char operator,(flag, T const&);
|
|
|
|
char operator,(int, flag);
|
|
int operator,(char, flag);
|
|
}
|
|
|
|
template <typename T>
|
|
inline bool Node::Read(T& value) const {
|
|
using namespace fallback;
|
|
|
|
return read_impl<sizeof (fallback::flag(), Convert(std::string(), value), fallback::flag()) != 1>::read(*this, value);
|
|
}
|
|
#endif // done with trick
|
|
|
|
// the main conversion function
|
|
template <typename T>
|
|
inline bool ConvertScalar(const Node& node, T& value) {
|
|
std::string scalar;
|
|
if(!node.GetScalar(scalar))
|
|
return false;
|
|
|
|
return Convert(scalar, value);
|
|
}
|
|
}
|