summaryrefslogtreecommitdiffstats
path: root/yaml-cpp/include/yaml-cpp/nodereadimpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'yaml-cpp/include/yaml-cpp/nodereadimpl.h')
-rwxr-xr-xyaml-cpp/include/yaml-cpp/nodereadimpl.h86
1 files changed, 86 insertions, 0 deletions
diff --git a/yaml-cpp/include/yaml-cpp/nodereadimpl.h b/yaml-cpp/include/yaml-cpp/nodereadimpl.h
new file mode 100755
index 00000000..6838dc5a
--- /dev/null
+++ b/yaml-cpp/include/yaml-cpp/nodereadimpl.h
@@ -0,0 +1,86 @@
+#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 <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);
+ }
+}
+
+#endif // NODEREADIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66