Converted indexing to std::size_t, and fixed the Node templated overloads to properly index any index type (determining what is an index type is a bit of a hack - it should be is_convertible<T, std::size_t> (I think), but I just explicitly wrote down a list)

This commit is contained in:
Jesse Beder 2009-08-19 20:58:07 +00:00
parent ba11f5ae15
commit 81c2e6b6ca
17 changed files with 134 additions and 78 deletions

View File

@ -40,7 +40,7 @@ namespace YAML
// accessors // accessors
Iterator begin() const; Iterator begin() const;
Iterator end() const; Iterator end() const;
unsigned size() const; std::size_t size() const;
// extraction of scalars // extraction of scalars
bool GetScalar(std::string& s) const; bool GetScalar(std::string& s) const;
@ -55,18 +55,16 @@ namespace YAML
template <typename T> template <typename T>
friend void operator >> (const Node& node, T& value); friend void operator >> (const Node& node, T& value);
// just for maps // retrieval for maps and sequences
template <typename T> template <typename T>
const Node *FindValue(const T& key) const; const Node *FindValue(const T& key) const;
const Node *FindValue(const char *key) const;
template <typename T> template <typename T>
const Node& operator [] (const T& key) const; const Node& operator [] (const T& key) const;
const Node& operator [] (const char *key) const;
// just for sequences // specific to maps
const Node& operator [] (unsigned u) const; const Node *FindValue(const char *key) const;
const Node& operator [] (int i) const; const Node& operator [] (const char *key) const;
// for anchors/aliases // for anchors/aliases
const Node *Identity() const { return m_pIdentity; } const Node *Identity() const { return m_pIdentity; }
@ -81,10 +79,17 @@ namespace YAML
friend bool operator < (const Node& n1, const Node& n2); friend bool operator < (const Node& n1, const Node& n2);
private: private:
// helper for sequences
template <typename, bool> friend struct _FindFromNodeAtIndex;
const Node *FindAtIndex(std::size_t i) const;
// helper for maps // helper for maps
template <typename T> template <typename T>
const Node& GetValue(const T& key) const; const Node& GetValue(const T& key) const;
template <typename T>
const Node *FindValueForKey(const T& key) const;
// helpers for parsing // helpers for parsing
void ParseHeader(Scanner *pScanner, const ParserState& state); void ParseHeader(Scanner *pScanner, const ParserState& state);
void ParseTag(Scanner *pScanner, const ParserState& state); void ParseTag(Scanner *pScanner, const ParserState& state);

View File

@ -4,6 +4,8 @@
#define NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODEIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "nodeutil.h"
namespace YAML namespace YAML
{ {
// implementation of templated things // implementation of templated things
@ -31,9 +33,18 @@ namespace YAML
template <typename T> template <typename T>
inline const Node *Node::FindValue(const T& key) const { inline const Node *Node::FindValue(const T& key) const {
if(!m_pContent) switch(GetType()) {
return 0; case CT_MAP:
return FindValueForKey(key);
case CT_SEQUENCE:
return FindFromNodeAtIndex(*this, key);
default:
return 0;
}
}
template <typename T>
inline const Node *Node::FindValueForKey(const T& key) const {
for(Iterator it=begin();it!=end();++it) { for(Iterator it=begin();it!=end();++it) {
T t; T t;
if(it.first().Read(t)) { if(it.first().Read(t)) {
@ -45,24 +56,16 @@ namespace YAML
return 0; return 0;
} }
inline const Node *Node::FindValue(const char *key) const {
return FindValue(std::string(key));
}
template <typename T> template <typename T>
inline const Node& Node::GetValue(const T& key) const { inline const Node& Node::GetValue(const T& key) const {
if(!m_pContent) if(!m_pContent)
throw BadDereference(); throw BadDereference();
for(Iterator it=begin();it!=end();++it) { const Node *pValue = FindValue(key);
T t; if(!pValue)
if(it.first().Read(t)) { throw MakeTypedKeyNotFound(m_mark, key);
if(key == t)
return it.second();
}
}
throw MakeTypedKeyNotFound(m_mark, key); return *pValue;
} }
template <typename T> template <typename T>
@ -70,6 +73,10 @@ namespace YAML
return GetValue(key); return GetValue(key);
} }
inline const Node *Node::FindValue(const char *key) const {
return FindValue(std::string(key));
}
inline const Node& Node::operator [] (const char *key) const { inline const Node& Node::operator [] (const char *key) const {
return GetValue(std::string(key)); return GetValue(std::string(key));
} }

60
include/nodeutil.h Normal file
View File

@ -0,0 +1,60 @@
#pragma once
#ifndef NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
template <typename T, typename U>
struct is_same_type {
enum { value = false };
};
template <typename T>
struct is_same_type<T, T> {
enum { value = true };
};
template <typename T, bool check>
struct is_index_type_with_check {
enum { value = false };
};
template <> struct is_index_type_with_check<std::size_t, false> { enum { value = true }; };
#define MAKE_INDEX_TYPE(Type) \
template <> struct is_index_type_with_check<Type, is_same_type<Type, std::size_t>::value> { enum { value = true }; }
MAKE_INDEX_TYPE(int);
MAKE_INDEX_TYPE(unsigned);
MAKE_INDEX_TYPE(short);
MAKE_INDEX_TYPE(unsigned short);
MAKE_INDEX_TYPE(long);
MAKE_INDEX_TYPE(unsigned long);
#undef MAKE_INDEX_TYPE;
template <typename T>
struct is_index_type: public is_index_type_with_check<T, false> {};
// messing around with template stuff to get the right overload for operator [] for a sequence
template <typename T, bool b>
struct _FindFromNodeAtIndex {
const Node *pRet;
_FindFromNodeAtIndex(const Node&, const T&): pRet(0) {}
};
template <typename T>
struct _FindFromNodeAtIndex<T, true> {
const Node *pRet;
_FindFromNodeAtIndex(const Node& node, const T& key): pRet(node.FindAtIndex(static_cast<std::size_t>(key))) {}
};
template <typename T>
inline const Node *FindFromNodeAtIndex(const Node& node, const T& key) {
return _FindFromNodeAtIndex<T, is_index_type<T>::value>(node, key).pRet;
}
}
#endif // NODEUTIL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@ -37,12 +37,12 @@ namespace YAML
return m_pRef->GetEnd(i); return m_pRef->GetEnd(i);
} }
Node* AliasContent::GetNode(unsigned n) const Node* AliasContent::GetNode(std::size_t n) const
{ {
return m_pRef->GetNode(n); return m_pRef->GetNode(n);
} }
unsigned AliasContent::GetSize() const std::size_t AliasContent::GetSize() const
{ {
return m_pRef->GetSize(); return m_pRef->GetSize();
} }

View File

@ -20,8 +20,8 @@ namespace YAML
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const; virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const;
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const; virtual bool GetEnd(std::vector <Node *>::const_iterator&) const;
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const; virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const;
virtual Node* GetNode(unsigned) const; virtual Node* GetNode(std::size_t) const;
virtual unsigned GetSize() const; virtual std::size_t GetSize() const;
virtual bool IsScalar() const; virtual bool IsScalar() const;
virtual bool IsMap() const; virtual bool IsMap() const;
virtual bool IsSequence() const; virtual bool IsSequence() const;

View File

@ -33,8 +33,8 @@ namespace YAML
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; } virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
virtual bool GetEnd(std::vector <Node *>::const_iterator&) const { return false; } virtual bool GetEnd(std::vector <Node *>::const_iterator&) const { return false; }
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; } virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
virtual Node *GetNode(unsigned) const { return 0; } virtual Node *GetNode(std::size_t) const { return 0; }
virtual unsigned GetSize() const { return 0; } virtual std::size_t GetSize() const { return 0; }
virtual bool IsScalar() const { return false; } virtual bool IsScalar() const { return false; }
virtual bool IsMap() const { return false; } virtual bool IsMap() const { return false; }
virtual bool IsSequence() const { return false; } virtual bool IsSequence() const { return false; }

View File

@ -22,7 +22,7 @@ namespace
template <typename T> template <typename T>
bool IsEntirely(const std::string& str, T func) bool IsEntirely(const std::string& str, T func)
{ {
for(unsigned i=0;i<str.size();i++) for(std::size_t i=0;i<str.size();i++)
if(!func(str[i])) if(!func(str[i]))
return false; return false;

View File

@ -54,7 +54,7 @@ namespace YAML
bool WriteSingleQuotedString(ostream& out, const std::string& str) bool WriteSingleQuotedString(ostream& out, const std::string& str)
{ {
out << "'"; out << "'";
for(unsigned i=0;i<str.size();i++) { for(std::size_t i=0;i<str.size();i++) {
char ch = str[i]; char ch = str[i];
if(!IsPrintable(ch)) if(!IsPrintable(ch))
return false; return false;
@ -71,7 +71,7 @@ namespace YAML
bool WriteDoubleQuotedString(ostream& out, const std::string& str) bool WriteDoubleQuotedString(ostream& out, const std::string& str)
{ {
out << "\""; out << "\"";
for(unsigned i=0;i<str.size();i++) { for(std::size_t i=0;i<str.size();i++) {
char ch = str[i]; char ch = str[i];
if(IsPrintable(ch)) { if(IsPrintable(ch)) {
if(ch == '\"') if(ch == '\"')
@ -95,7 +95,7 @@ namespace YAML
{ {
out << "|\n"; out << "|\n";
out << IndentTo(indent); out << IndentTo(indent);
for(unsigned i=0;i<str.size();i++) { for(std::size_t i=0;i<str.size();i++) {
if(str[i] == '\n') if(str[i] == '\n')
out << "\n" << IndentTo(indent); out << "\n" << IndentTo(indent);
else else
@ -108,7 +108,7 @@ namespace YAML
{ {
unsigned curIndent = out.col(); unsigned curIndent = out.col();
out << "#" << Indentation(postCommentIndent); out << "#" << Indentation(postCommentIndent);
for(unsigned i=0;i<str.size();i++) { for(std::size_t i=0;i<str.size();i++) {
if(str[i] == '\n') if(str[i] == '\n')
out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent); out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
else else
@ -120,7 +120,7 @@ namespace YAML
bool WriteAlias(ostream& out, const std::string& str) bool WriteAlias(ostream& out, const std::string& str)
{ {
out << "*"; out << "*";
for(unsigned i=0;i<str.size();i++) { for(std::size_t i=0;i<str.size();i++) {
if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r') if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r')
return false; return false;
@ -132,7 +132,7 @@ namespace YAML
bool WriteAnchor(ostream& out, const std::string& str) bool WriteAnchor(ostream& out, const std::string& str)
{ {
out << "&"; out << "&";
for(unsigned i=0;i<str.size();i++) { for(std::size_t i=0;i<str.size();i++) {
if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r') if(!IsPrintable(str[i]) || str[i] == ' ' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r')
return false; return false;

View File

@ -10,7 +10,7 @@ namespace YAML
unsigned ParseHex(const std::string& str, const Mark& mark) unsigned ParseHex(const std::string& str, const Mark& mark)
{ {
unsigned value = 0; unsigned value = 0;
for(unsigned i=0;i<str.size();i++) { for(std::size_t i=0;i<str.size();i++) {
char ch = str[i]; char ch = str[i];
int digit = 0; int digit = 0;
if('a' <= ch && ch <= 'f') if('a' <= ch && ch <= 'f')

View File

@ -126,7 +126,7 @@ namespace YAML
m_tag = state.TranslateTag(token.value); m_tag = state.TranslateTag(token.value);
for(unsigned i=0;i<token.params.size();i++) for(std::size_t i=0;i<token.params.size();i++)
m_tag += token.params[i]; m_tag += token.params[i];
pScanner->pop(); pScanner->pop();
} }
@ -209,7 +209,7 @@ namespace YAML
// size // size
// . Returns the size of this node, if it's a sequence node. // . Returns the size of this node, if it's a sequence node.
// . Otherwise, returns zero. // . Otherwise, returns zero.
unsigned Node::size() const std::size_t Node::size() const
{ {
if(!m_pContent) if(!m_pContent)
return 0; return 0;
@ -217,28 +217,12 @@ namespace YAML
return m_pContent->GetSize(); return m_pContent->GetSize();
} }
const Node& Node::operator [] (unsigned u) const const Node *Node::FindAtIndex(std::size_t i) const
{ {
if(!m_pContent) if(!m_pContent)
throw BadDereference(); return 0;
Node *pNode = m_pContent->GetNode(u); return m_pContent->GetNode(i);
if(pNode)
return *pNode;
return GetValue(u);
}
const Node& Node::operator [] (int i) const
{
if(!m_pContent)
throw BadDereference();
Node *pNode = m_pContent->GetNode(i);
if(pNode)
return *pNode;
return GetValue(i);
} }
bool Node::GetScalar(std::string& s) const bool Node::GetScalar(std::string& s) const

View File

@ -43,8 +43,8 @@ namespace YAML
ostream& operator << (ostream& out, const char *str) ostream& operator << (ostream& out, const char *str)
{ {
unsigned length = std::strlen(str); std::size_t length = std::strlen(str);
for(unsigned i=0;i<length;i++) for(std::size_t i=0;i<length;i++)
out.put(str[i]); out.put(str[i]);
return out; return out;
} }

View File

@ -22,7 +22,7 @@ namespace YAML
RegEx::RegEx(const std::string& str, REGEX_OP op): m_op(op) RegEx::RegEx(const std::string& str, REGEX_OP op): m_op(op)
{ {
for(unsigned i=0;i<str.size();i++) for(std::size_t i=0;i<str.size();i++)
m_params.push_back(RegEx(str[i])); m_params.push_back(RegEx(str[i]));
} }

View File

@ -125,7 +125,7 @@ namespace YAML
// OrOperator // OrOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpOr(const Source& source) const { inline int RegEx::MatchOpOr(const Source& source) const {
for(unsigned i=0;i<m_params.size();i++) { for(std::size_t i=0;i<m_params.size();i++) {
int n = m_params[i].MatchUnchecked(source); int n = m_params[i].MatchUnchecked(source);
if(n >= 0) if(n >= 0)
return n; return n;
@ -140,7 +140,7 @@ namespace YAML
template <typename Source> template <typename Source>
inline int RegEx::MatchOpAnd(const Source& source) const { inline int RegEx::MatchOpAnd(const Source& source) const {
int first = -1; int first = -1;
for(unsigned i=0;i<m_params.size();i++) { for(std::size_t i=0;i<m_params.size();i++) {
int n = m_params[i].MatchUnchecked(source); int n = m_params[i].MatchUnchecked(source);
if(n == -1) if(n == -1)
return -1; return -1;
@ -164,7 +164,7 @@ namespace YAML
template <typename Source> template <typename Source>
inline int RegEx::MatchOpSeq(const Source& source) const { inline int RegEx::MatchOpSeq(const Source& source) const {
int offset = 0; int offset = 0;
for(unsigned i=0;i<m_params.size();i++) { for(std::size_t i=0;i<m_params.size();i++) {
int n = m_params[i].Match(source + offset); // note Match, not MatchUnchecked because we need to check validity after the offset int n = m_params[i].Match(source + offset); // note Match, not MatchUnchecked because we need to check validity after the offset
if(n == -1) if(n == -1)
return -1; return -1;

View File

@ -136,13 +136,13 @@ namespace YAML
// post-processing // post-processing
if(params.trimTrailingSpaces) { if(params.trimTrailingSpaces) {
unsigned pos = scalar.find_last_not_of(' '); std::size_t pos = scalar.find_last_not_of(' ');
if(pos < scalar.size()) if(pos < scalar.size())
scalar.erase(pos + 1); scalar.erase(pos + 1);
} }
if(params.chomp <= 0) { if(params.chomp <= 0) {
unsigned pos = scalar.find_last_not_of('\n'); std::size_t pos = scalar.find_last_not_of('\n');
if(params.chomp == 0 && pos + 1 < scalar.size()) if(params.chomp == 0 && pos + 1 < scalar.size())
scalar.erase(pos + 2); scalar.erase(pos + 2);
else if(params.chomp == -1 && pos < scalar.size()) else if(params.chomp == -1 && pos < scalar.size())

View File

@ -20,7 +20,7 @@ namespace YAML
void Sequence::Clear() void Sequence::Clear()
{ {
for(unsigned i=0;i<m_data.size();i++) for(std::size_t i=0;i<m_data.size();i++)
delete m_data[i]; delete m_data[i];
m_data.clear(); m_data.clear();
} }
@ -37,14 +37,14 @@ namespace YAML
return true; return true;
} }
Node *Sequence::GetNode(unsigned i) const Node *Sequence::GetNode(std::size_t i) const
{ {
if(i < m_data.size()) if(i < m_data.size())
return m_data[i]; return m_data[i];
return 0; return 0;
} }
unsigned Sequence::GetSize() const std::size_t Sequence::GetSize() const
{ {
return m_data.size(); return m_data.size();
} }
@ -145,7 +145,7 @@ namespace YAML
void Sequence::Write(Emitter& out) const void Sequence::Write(Emitter& out) const
{ {
out << BeginSeq; out << BeginSeq;
for(unsigned i=0;i<m_data.size();i++) for(std::size_t i=0;i<m_data.size();i++)
out << *m_data[i]; out << *m_data[i];
out << EndSeq; out << EndSeq;
} }
@ -157,13 +157,13 @@ namespace YAML
int Sequence::Compare(Sequence *pSeq) int Sequence::Compare(Sequence *pSeq)
{ {
unsigned n = m_data.size(), m = pSeq->m_data.size(); std::size_t n = m_data.size(), m = pSeq->m_data.size();
if(n < m) if(n < m)
return -1; return -1;
else if(n > m) else if(n > m)
return 1; return 1;
for(unsigned i=0;i<n;i++) { for(std::size_t i=0;i<n;i++) {
int cmp = m_data[i]->Compare(*pSeq->m_data[i]); int cmp = m_data[i]->Compare(*pSeq->m_data[i]);
if(cmp != 0) if(cmp != 0)
return cmp; return cmp;

View File

@ -20,8 +20,8 @@ namespace YAML
void Clear(); void Clear();
virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const; virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const;
virtual bool GetEnd(std::vector <Node *>::const_iterator& it) const; virtual bool GetEnd(std::vector <Node *>::const_iterator& it) const;
virtual Node *GetNode(unsigned i) const; virtual Node *GetNode(std::size_t i) const;
virtual unsigned GetSize() const; virtual std::size_t GetSize() const;
virtual void Parse(Scanner *pScanner, const ParserState& state); virtual void Parse(Scanner *pScanner, const ParserState& state);
virtual void Write(Emitter& out) const; virtual void Write(Emitter& out) const;

View File

@ -59,7 +59,7 @@ namespace YAML
friend std::ostream& operator << (std::ostream& out, const Token& token) { friend std::ostream& operator << (std::ostream& out, const Token& token) {
out << TokenNames[token.type] << std::string(": ") << token.value; out << TokenNames[token.type] << std::string(": ") << token.value;
for(unsigned i=0;i<token.params.size();i++) for(std::size_t i=0;i<token.params.size();i++)
out << std::string(" ") << token.params[i]; out << std::string(" ") << token.params[i];
return out; return out;
} }