diff --git a/include/node.h b/include/node.h index 0ac945c..f970f4f 100644 --- a/include/node.h +++ b/include/node.h @@ -32,45 +32,35 @@ namespace YAML Iterator end() const; unsigned size() const; + // extraction of scalars + bool Read(std::string& s) const; + bool Read(int& i) const; + bool Read(unsigned& u) const; + bool Read(long& l) const; + bool Read(float& f) const; + bool Read(double& d) const; + bool Read(char& c) const; + + // so you can specialize for other values template - const Node& GetValue(const T& key) const { - if(!m_pContent) - throw BadDereference(); - - for(Iterator it=begin();it!=end();++it) { - T t; - try { - it.first() >> t; - if(key == t) - return it.second(); - } catch(RepresentationException&) { - } - } - - throw BadDereference(); - } + friend bool Read(const Node& node, T& value); template - const Node& operator [] (const T& key) const { - return GetValue(key); - } + friend void operator >> (const Node& node, T& value); - const Node& operator [] (const char *key) const { - return GetValue(std::string(key)); - } + // just for maps + template + const Node& GetValue(const T& key) const; + template + const Node& operator [] (const T& key) const; + + const Node& operator [] (const char *key) const; + + // just for sequences const Node& operator [] (unsigned u) const; const Node& operator [] (int i) const; - // extraction - friend void operator >> (const Node& node, std::string& s); - friend void operator >> (const Node& node, int& i); - friend void operator >> (const Node& node, unsigned& u); - friend void operator >> (const Node& node, long& l); - friend void operator >> (const Node& node, float& f); - friend void operator >> (const Node& node, double& d); - friend void operator >> (const Node& node, char& c); - // insertion friend std::ostream& operator << (std::ostream& out, const Node& node); @@ -94,4 +84,46 @@ namespace YAML Content *m_pContent; bool m_alias; }; + + // templated things we need to keep inline in the header + template + inline bool Read(const Node& node, T& value) + { + return node.Read(value); + } + + template + inline void operator >> (const Node& node, T& value) + { + if(!Read(node, value)) + throw InvalidScalar(); + } + + template + inline const Node& Node::GetValue(const T& key) const + { + if(!m_pContent) + throw BadDereference(); + + for(Iterator it=begin();it!=end();++it) { + T t; + if(YAML::Read(it.first(), t)) { + if(key == t) + return it.second(); + } + } + + throw BadDereference(); + } + + template + inline const Node& Node::operator [] (const T& key) const + { + return GetValue(key); + } + + inline const Node& Node::operator [] (const char *key) const + { + return GetValue(std::string(key)); + } } diff --git a/src/content.h b/src/content.h index b7a5da9..9561a4b 100644 --- a/src/content.h +++ b/src/content.h @@ -36,13 +36,13 @@ namespace YAML virtual bool IsSequence() const { return false; } // extraction - virtual void Read(std::string& s) { throw InvalidScalar(); } - virtual void Read(int& i) { throw InvalidScalar(); } - virtual void Read(unsigned& u) { throw InvalidScalar(); } - virtual void Read(long& l) { throw InvalidScalar(); } - virtual void Read(float& f) { throw InvalidScalar(); } - virtual void Read(double& d) { throw InvalidScalar(); } - virtual void Read(char& c) { throw InvalidScalar(); } + virtual bool Read(std::string& s) const { return false; } + virtual bool Read(int& i) const { return false; } + virtual bool Read(unsigned& u) const { return false; } + virtual bool Read(long& l) const { return false; } + virtual bool Read(float& f) const { return false; } + virtual bool Read(double& d) const { return false; } + virtual bool Read(char& c) const { return false; } // ordering virtual int Compare(Content *pContent) { return 0; } diff --git a/src/node.cpp b/src/node.cpp index f009903..df79ad4 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -232,61 +232,65 @@ namespace YAML /////////////////////////////////////////////////////// // Extraction + // Note: these Read() functions are identical, but + // they're not templated because they use a Content virtual + // function, so we'd have to #include that in node.h, and + // I don't want to. - void operator >> (const Node& node, std::string& s) + bool Node::Read(std::string& s) const { - if(!node.m_pContent) - throw; + if(!m_pContent) + return false; - node.m_pContent->Read(s); + return m_pContent->Read(s); } - void operator >> (const Node& node, int& i) + bool Node::Read(int& i) const { - if(!node.m_pContent) - throw; + if(!m_pContent) + return false; - node.m_pContent->Read(i); + return m_pContent->Read(i); } - void operator >> (const Node& node, unsigned& u) + bool Node::Read(unsigned& u) const { - if(!node.m_pContent) - throw; + if(!m_pContent) + return false; - node.m_pContent->Read(u); + return m_pContent->Read(u); } - void operator >> (const Node& node, long& l) + bool Node::Read(long& l) const { - if(!node.m_pContent) - throw; + if(!m_pContent) + return false; - node.m_pContent->Read(l); + return m_pContent->Read(l); } - void operator >> (const Node& node, float& f) + bool Node::Read(float& f) const { - if(!node.m_pContent) - throw; + if(!m_pContent) + return false; - node.m_pContent->Read(f); + return m_pContent->Read(f); } - void operator >> (const Node& node, double& d) + bool Node::Read(double& d) const { - if(!node.m_pContent) - throw; + if(!m_pContent) + return false; - node.m_pContent->Read(d); + return m_pContent->Read(d); } - void operator >> (const Node& node, char& c) + bool Node::Read(char& c) const { - if(!node.m_pContent) - throw; + if(!m_pContent) + return false; - node.m_pContent->Read(c); + return m_pContent->Read(c); } std::ostream& operator << (std::ostream& out, const Node& node) diff --git a/src/scalar.cpp b/src/scalar.cpp index ed8f032..00985cb 100644 --- a/src/scalar.cpp +++ b/src/scalar.cpp @@ -38,57 +38,52 @@ namespace YAML out << "\"\n"; } - void Scalar::Read(std::string& s) + bool Scalar::Read(std::string& s) const { s = m_data; + return true; } - void Scalar::Read(int& i) + bool Scalar::Read(int& i) const { std::stringstream data(m_data); data >> i; - if(!data) - throw InvalidScalar(); + return !data.fail(); } - void Scalar::Read(unsigned& u) + bool Scalar::Read(unsigned& u) const { std::stringstream data(m_data); data >> u; - if(!data) - throw InvalidScalar(); + return !data.fail(); } - void Scalar::Read(long& l) + bool Scalar::Read(long& l) const { std::stringstream data(m_data); data >> l; - if(!data) - throw InvalidScalar(); + return !data.fail(); } - void Scalar::Read(float& f) + bool Scalar::Read(float& f) const { std::stringstream data(m_data); data >> f; - if(!data) - throw InvalidScalar(); + return !data.fail(); } - void Scalar::Read(double& d) + bool Scalar::Read(double& d) const { std::stringstream data(m_data); data >> d; - if(!data) - throw InvalidScalar(); + return !data.fail(); } - void Scalar::Read(char& c) + bool Scalar::Read(char& c) const { std::stringstream data(m_data); data >> c; - if(!data) - throw InvalidScalar(); + return !data.fail(); } int Scalar::Compare(Content *pContent) diff --git a/src/scalar.h b/src/scalar.h index ea6e055..3dab558 100644 --- a/src/scalar.h +++ b/src/scalar.h @@ -17,13 +17,13 @@ namespace YAML virtual bool IsScalar() const { return true; } // extraction - virtual void Read(std::string& s); - virtual void Read(int& i); - virtual void Read(unsigned& u); - virtual void Read(long& l); - virtual void Read(float& f); - virtual void Read(double& d); - virtual void Read(char& c); + virtual bool Read(std::string& s) const; + virtual bool Read(int& i) const; + virtual bool Read(unsigned& u) const; + virtual bool Read(long& l) const; + virtual bool Read(float& f) const; + virtual bool Read(double& d) const; + virtual bool Read(char& c) const; // ordering virtual int Compare(Content *pContent);