Refactored the traits a bit, and added displaying the key to string and numeric key not found errors

This commit is contained in:
jbeder
2009-11-12 17:00:12 +00:00
parent 7b33c7c4b4
commit bbf510d6cc
4 changed files with 110 additions and 34 deletions

View File

@@ -5,6 +5,7 @@
#include "null.h"
#include "traits.h"
#include <string>
#include <sstream>
@@ -18,34 +19,8 @@ namespace YAML
bool Convert(const std::string& input, bool& output);
bool Convert(const std::string& input, _Null& output);
template <typename>
struct is_numeric { enum { value = false }; };
template <> struct is_numeric <char> { enum { value = true }; };
template <> struct is_numeric <unsigned char> { enum { value = true }; };
template <> struct is_numeric <int> { enum { value = true }; };
template <> struct is_numeric <unsigned int> { enum { value = true }; };
template <> struct is_numeric <long int> { enum { value = true }; };
template <> struct is_numeric <unsigned long int> { enum { value = true }; };
template <> struct is_numeric <short int> { enum { value = true }; };
template <> struct is_numeric <unsigned short int> { enum { value = true }; };
template <> struct is_numeric <long long> { enum { value = true }; };
template <> struct is_numeric <unsigned long long> { enum { value = true }; };
template <> struct is_numeric <float> { enum { value = true }; };
template <> struct is_numeric <double> { enum { value = true }; };
template <> struct is_numeric <long double> { enum { value = true }; };
template <typename T, typename, bool = T::value>
struct enable_if;
template <typename T, typename R>
struct enable_if <T, R, true> {
typedef R type;
};
template <typename T>
inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T>, T>::type * = 0) {
inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T> >::type * = 0) {
std::stringstream stream(input);
stream.unsetf(std::ios::dec);
return stream >> output;

View File

@@ -5,6 +5,7 @@
#include "mark.h"
#include "traits.h"
#include <exception>
#include <string>
#include <sstream>
@@ -67,6 +68,22 @@ namespace YAML
const std::string EXPECTED_VALUE_TOKEN = "expected value token";
const std::string UNEXPECTED_KEY_TOKEN = "unexpected key token";
const std::string UNEXPECTED_VALUE_TOKEN = "unexpected value token";
template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) {
return KEY_NOT_FOUND;
}
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
return KEY_NOT_FOUND + ": " + key;
}
template <typename T>
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) {
std::stringstream stream;
stream << KEY_NOT_FOUND << ": " << key;
return stream.str();
}
}
class Exception: public std::exception {
@@ -108,22 +125,23 @@ namespace YAML
class KeyNotFound: public RepresentationException {
public:
KeyNotFound(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND) {}
template <typename T>
KeyNotFound(const Mark& mark_, const T& key_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {}
};
template <typename T>
class TypedKeyNotFound: public KeyNotFound {
public:
TypedKeyNotFound(const Mark& mark_, const T& key_)
: KeyNotFound(mark_), key(key_) {}
~TypedKeyNotFound() throw() {}
: KeyNotFound(mark_, key_), key(key_) {}
virtual ~TypedKeyNotFound() throw() {}
T key;
};
template <typename T>
TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
return TypedKeyNotFound <T> (mark, key);
}

50
include/traits.h Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
namespace YAML
{
template <typename>
struct is_numeric { enum { value = false }; };
template <> struct is_numeric <char> { enum { value = true }; };
template <> struct is_numeric <unsigned char> { enum { value = true }; };
template <> struct is_numeric <int> { enum { value = true }; };
template <> struct is_numeric <unsigned int> { enum { value = true }; };
template <> struct is_numeric <long int> { enum { value = true }; };
template <> struct is_numeric <unsigned long int> { enum { value = true }; };
template <> struct is_numeric <short int> { enum { value = true }; };
template <> struct is_numeric <unsigned short int> { enum { value = true }; };
template <> struct is_numeric <long long> { enum { value = true }; };
template <> struct is_numeric <unsigned long long> { enum { value = true }; };
template <> struct is_numeric <float> { enum { value = true }; };
template <> struct is_numeric <double> { enum { value = true }; };
template <> struct is_numeric <long double> { enum { value = true }; };
template <bool, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool, class T = void>
struct disable_if_c {
typedef T type;
};
template <class T>
struct disable_if_c<true, T> {};
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
}
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -657,6 +657,38 @@ namespace Test
return false;
return true;
}
bool KeyNotFound()
{
std::string input = "key: value";
std::stringstream stream(input);
YAML::Parser parser(stream);
YAML::Node doc;
parser.GetNextDocument(doc);
try {
doc["bad key"];
} catch(const YAML::Exception& e) {
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": bad key")
throw;
}
try {
doc[5];
} catch(const YAML::Exception& e) {
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": 5")
throw;
}
try {
doc[2.5];
} catch(const YAML::Exception& e) {
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": 2.5")
throw;
}
return true;
}
}
namespace {
@@ -674,7 +706,7 @@ namespace Test
doc >> output;
} catch(const YAML::Exception& e) {
ok = false;
error = e.msg;
error = e.what();
}
if(ok && output == desiredOutput) {
passed++;
@@ -918,6 +950,7 @@ namespace Test
RunParserTest(&Parser::MultipleDocsWithSomeExplicitIndicators, "multiple docs with some explicit indicators", passed, total);
RunParserTest(&Parser::BlockKeyWithNullValue, "block key with null value", passed, total);
RunParserTest(&Parser::Bases, "bases", passed, total);
RunParserTest(&Parser::KeyNotFound, "key not found", passed, total);
RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total);
RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);