From f219bab21c07d02e7e54d557e23387bd93c9ce5f Mon Sep 17 00:00:00 2001
From: Patrick Simianer
Date: Sat, 19 Jul 2014 08:30:43 +0200
Subject: hg io
---
fast/json-cpp.hpp | 1231 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 1231 insertions(+)
create mode 100644 fast/json-cpp.hpp
(limited to 'fast/json-cpp.hpp')
diff --git a/fast/json-cpp.hpp b/fast/json-cpp.hpp
new file mode 100644
index 0000000..851a4f4
--- /dev/null
+++ b/fast/json-cpp.hpp
@@ -0,0 +1,1231 @@
+//
+// DO NOT EDIT !!! This file was generated with a script.
+//
+// JSON for C++
+// https://github.com/ascheglov/json-cpp
+// Version 0.1 alpha, rev. 170121e2dc099895064305e38bfb25d90a807ce3
+// Generated 2014-03-27 17:16:47.104492 UTC
+//
+// Belongs to the public domain
+
+#pragma once
+
+//----------------------------------------------------------------------
+// json-cpp.hpp begin
+
+//----------------------------------------------------------------------
+// json-cpp/parse.hpp begin
+
+#include
+#include
+#include
+#include
+#include
+
+//----------------------------------------------------------------------
+// json-cpp/ParserError.hpp begin
+
+#include
+#include
+#include
+#include
+
+#if defined _MSC_VER
+# define JSONCPP_INTERNAL_NOEXCEPT_ throw()
+#else
+# define JSONCPP_INTERNAL_NOEXCEPT_ noexcept
+#endif
+
+namespace jsoncpp
+{
+ class ParserError : public std::exception
+ {
+ public:
+ enum Type
+ {
+ NoError,
+ Eof, UnexpectedCharacter,
+ InvalidEscapeSequence, NoTrailSurrogate,
+ UnexpectedType, UnknownField,
+ NumberIsOutOfRange,
+ };
+
+ ParserError(Type type, std::size_t line, std::size_t column)
+ : m_type{type}, m_line{line}, m_column{column}
+ {
+ assert(type != NoError);
+ }
+
+ virtual const char* what() const JSONCPP_INTERNAL_NOEXCEPT_ override
+ {
+ if (m_what.empty())
+ {
+ m_what = "JSON parser error at line ";
+ m_what += std::to_string(m_line);
+ m_what += ", column ";
+ m_what += std::to_string(m_column);
+ switch (m_type)
+ {
+ case Eof: m_what += ": unexpected end of file"; break;
+ case UnexpectedCharacter: m_what += ": unexpected character"; break;
+ case InvalidEscapeSequence: m_what += ": invalid escape sequence"; break;
+ case NoTrailSurrogate: m_what += ": no UTF-16 trail surrogate"; break;
+ case UnexpectedType: m_what += ": unexpected value type"; break;
+ case UnknownField: m_what += ": unknown field name"; break;
+ case NumberIsOutOfRange: m_what += ": number is out of range"; break;
+ case NoError:
+ default:
+ m_what += ": INTERNAL ERROR"; break;
+ }
+ }
+
+ return m_what.c_str();
+ }
+
+ Type type() const { return m_type; }
+ std::size_t line() const { return m_line; }
+ std::size_t column() const { return m_column; }
+
+ private:
+ Type m_type;
+ std::size_t m_line;
+ std::size_t m_column;
+
+ mutable std::string m_what;
+ };
+}
+
+#undef JSONCPP_INTERNAL_NOEXCEPT_
+
+// json-cpp/ParserError.hpp end
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// json-cpp/Stream.hpp begin
+
+namespace jsoncpp
+{
+ template
+ class Stream;
+
+ namespace details
+ {
+ template
+ struct Traits2 {};
+
+ template
+ struct ParserTraits {};
+
+ template
+ struct GeneratorTraits {};
+ }
+
+ template
+ using Parser = Stream>;
+
+ template
+ using Generator = Stream>;
+
+ template
+ inline auto serialize(Stream& stream, T& value) -> decltype(value.serialize(stream), void())
+ {
+ value.serialize(stream);
+ }
+}
+// json-cpp/Stream.hpp end
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// json-cpp/value_types.hpp begin
+
+namespace jsoncpp
+{
+ // Helper masks
+ const auto TypeIsNotFundamental = 0x40;
+ const auto TypeIsCollection = 0x80;
+
+ enum class Type
+ {
+ Undefined = 0, // Helper type for debugging variant-like types
+ Null = 0x01,
+ Boolean = 0x02,
+ Number = 0x04,
+ String = 0x08 | TypeIsNotFundamental,
+ Array = 0x10 | TypeIsNotFundamental | TypeIsCollection,
+ Object = 0x20 | TypeIsNotFundamental | TypeIsCollection,
+ };
+}
+// json-cpp/value_types.hpp end
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// json-cpp/details/parser_utility.hpp begin
+
+#include
+#include
+#include
+
+namespace jsoncpp { namespace details
+{
+ template
+ struct CStrIterator
+ {
+ using this_type = CStrIterator;
+
+ CStrIterator()
+ {
+ static CharT null{0};
+ m_ptr = &null;
+ }
+
+ CStrIterator(const CharT* ptr) : m_ptr{ptr} {}
+
+ const CharT& operator*() { return *m_ptr; }
+ const CharT* operator->() { return m_ptr; }
+
+ this_type& operator++()
+ {
+ assert(!isEnd());
+ ++m_ptr;
+ return *this;
+ }
+
+ this_type operator++(int) { auto temp = *this; ++*this; return temp; }
+
+ bool operator==(const this_type& rhs) const { return isEnd() == rhs.isEnd(); }
+ bool operator!=(const this_type& rhs) const { return !this->operator==(rhs); }
+
+ private:
+ const CharT* m_ptr;
+
+ bool isEnd() const { return *m_ptr == 0; }
+ };
+
+ class Diagnostics
+ {
+ public:
+ void nextColumn() { ++m_column; }
+ void newLine() { ++m_line; m_column = 0; }
+
+ ParserError makeError(ParserError::Type type) const
+ {
+ return{type, m_line, m_column};
+ }
+
+ private:
+ std::size_t m_column{0};
+ std::size_t m_line{1};
+ };
+
+ template
+ struct Reader
+ {
+ using this_type = Reader;
+
+ Reader(InputIterator first, InputIterator last) : m_iter(first), m_end(last)
+ {
+ checkEnd();
+ }
+
+ char operator*() { return *m_iter; }
+ this_type& operator++()
+ {
+ checkEnd();
+ ++m_iter;
+ m_diag.nextColumn();
+ return *this;
+ }
+
+ void checkEnd()
+ {
+ if (m_iter == m_end)
+ throw m_diag.makeError(ParserError::Eof);
+ }
+
+ char getNextChar()
+ {
+ auto prev = *m_iter;
+ ++*this;
+ return prev;
+ }
+
+ Diagnostics m_diag;
+ InputIterator m_iter, m_end;
+ };
+}}
+
+// json-cpp/details/parser_utility.hpp end
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// json-cpp/details/number_parser.hpp begin
+
+#include
+
+namespace jsoncpp { namespace details
+{
+ inline bool isDigit(char c) { return c >= '0' && c <= '9'; }
+
+ template
+ inline unsigned parseIntNumber(Iterator& iter)
+ {
+ auto intPart = 0U; // TBD: 0ULL ?
+
+ do
+ {
+ intPart = intPart * 10 + (*iter - '0');
+
+ ++iter;
+ }
+ while (isDigit(*iter));
+
+ return intPart;
+ }
+
+ template
+ inline double parseRealNumber(Iterator& iter)
+ {
+ double number = 0;
+
+ if (*iter == '0')
+ {
+ ++iter;
+ }
+ else
+ {
+ number = parseIntNumber(iter);
+ }
+
+ // here `ch` is a peeked character, need to call eat()
+
+ if (*iter == '.')
+ {
+ ++iter;
+
+ auto mul = 0.1;
+ while (isDigit(*iter))
+ {
+ number += (*iter - '0') * mul;
+ mul /= 10;
+ ++iter;
+ }
+ }
+
+ // here `ch` is a peeked character, need to call eat()
+
+ if (*iter == 'e' || *iter == 'E')
+ {
+ ++iter;
+
+ auto negate = *iter == '-';
+ if (negate || *iter == '+')
+ ++iter;
+ // FIXME: check `ch` for non-digit
+
+ auto e = parseIntNumber(iter);
+
+ if (negate)
+ number /= std::pow(10, e);
+ else
+ number *= std::pow(10, e);
+ }
+
+ return number;
+ }
+}}
+// json-cpp/details/number_parser.hpp end
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// json-cpp/details/string_parser.hpp begin
+
+#include
+
+namespace jsoncpp { namespace details
+{
+ inline char32_t utf16SurrogatePairToUtf32(char32_t lead, char32_t trail)
+ {
+ return 0x10000 | (lead - 0xD800) << 10 | (trail - 0xDC00);
+ }
+
+ inline void utf32ToUtf8(char32_t c, std::string& str)
+ {
+ auto add = [&str](char32_t c){ str.push_back(static_cast(c)); };
+
+ if (c < 0x80)
+ {
+ add(c);
+ }
+ else if (c < 0x800)
+ {
+ add(0xC0 | c >> 6);
+ add(0x80 | (c & 0x3f));
+ }
+ else if (c < 0x10000)
+ {
+ add(0xE0 | c >> 12);
+ add(0x80 | ((c >> 6) & 0x3f));
+ add(0x80 | (c & 0x3f));
+ }
+ else if (c < 0x200000)
+ {
+ add(0xF0 | c >> 18);
+ add(0x80 | ((c >> 12) & 0x3f));
+ add(0x80 | ((c >> 6) & 0x3f));
+ add(0x80 | (c & 0x3f));
+ }
+ else if (c < 0x4000000)
+ {
+ add(0xF8 | c >> 24);
+ add(0x80 | ((c >> 18) & 0x3f));
+ add(0x80 | ((c >> 12) & 0x3f));
+ add(0x80 | ((c >> 6) & 0x3f));
+ add(0x80 | (c & 0x3f));
+ }
+ else
+ {
+ add(0xFC | c >> 30);
+ add(0x80 | ((c >> 24) & 0x3f));
+ add(0x80 | ((c >> 18) & 0x3f));
+ add(0x80 | ((c >> 12) & 0x3f));
+ add(0x80 | ((c >> 6) & 0x3f));
+ add(0x80 | (c & 0x3f));
+ }
+ }
+
+ enum class CharType { Raw, CodePoint, UTF16Pair };
+
+ template
+ inline void addToStr(std::basic_string& str, CharType type, char32_t c1, char32_t c2);
+
+ template<>
+ inline void addToStr(std::basic_string& str, CharType type, char32_t c1, char32_t c2)
+ {
+ if (type == CharType::Raw)
+ {
+ str.push_back(static_cast(c1));
+ }
+ else if (type == CharType::CodePoint)
+ {
+ utf32ToUtf8(c1, str);
+ }
+ else
+ {
+ auto c32 = utf16SurrogatePairToUtf32(c1, c2);
+ utf32ToUtf8(c32, str);
+ }
+ }
+
+ template<>
+ inline void addToStr(std::basic_string& str, CharType type, char32_t c1, char32_t c2)
+ {
+ str.push_back(static_cast(c1));
+ if (type == CharType::UTF16Pair)
+ str.push_back(static_cast(c2));
+ }
+
+ template<>
+ inline void addToStr(std::basic_string& str, CharType type, char32_t c1, char32_t c2)
+ {
+ auto c = (type == CharType::UTF16Pair) ? utf16SurrogatePairToUtf32(c1, c2) : c1;
+ str.push_back(static_cast(c));
+ }
+
+ template
+ inline int parseHexDigit(Iterator& iter, ParserError::Type& err)
+ {
+ auto ch = *iter;
+ ++iter;
+ if (ch >= '0' && ch <= '9') return ch - '0';
+ if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
+ if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
+
+ err = ParserError::InvalidEscapeSequence;
+ return 0;
+ }
+
+ template
+ inline char32_t parseUTF16CodeUnit(Iterator& iter, ParserError::Type& err)
+ {
+ auto n = parseHexDigit(iter, err) << 12;
+ n |= parseHexDigit(iter, err) << 8;
+ n |= parseHexDigit(iter, err) << 4;
+ n |= parseHexDigit(iter, err);
+ return static_cast(n);
+ }
+
+ template
+ inline ParserError::Type parseStringImpl(Iterator& iter, std::basic_string& str)
+ {
+ str.clear();
+ auto add = [&str](CharType type, char32_t c1, char32_t c2)
+ {
+ addToStr(str, type, c1, c2);
+ };
+
+ for (;;)
+ {
+ auto ch = static_cast(*iter);
+ ++iter;
+ if (ch == '"')
+ return ParserError::NoError;
+
+ if (ch == '\\')
+ {
+ ch = static_cast(*iter);
+ ++iter;
+ switch (ch)
+ {
+ case '\\': case '"': case '/':
+ break;
+
+ case 'b': ch = '\b'; break;
+ case 'f': ch = '\f'; break;
+ case 'n': ch = '\n'; break;
+ case 'r': ch = '\r'; break;
+ case 't': ch = '\t'; break;
+
+ case 'u':
+ {
+ ParserError::Type err{ParserError::NoError};
+ auto codeUnit = parseUTF16CodeUnit(iter, err);
+ if (err != ParserError::NoError)
+ return err;
+
+ if (codeUnit >= 0xD800 && codeUnit < 0xDC00)
+ {
+ if (*iter != '\\') return ParserError::NoTrailSurrogate;
+ ++iter;
+ if (*iter != 'u') return ParserError::NoTrailSurrogate;
+ ++iter;
+
+ auto trailSurrogate = parseUTF16CodeUnit(iter, err);
+ if (err != ParserError::NoError)
+ return err;
+
+ add(CharType::UTF16Pair, codeUnit, trailSurrogate);
+ }
+ else
+ {
+ add(CharType::CodePoint, codeUnit, 0);
+ }
+ }
+ continue;
+
+ default:
+ return ParserError::InvalidEscapeSequence;
+ }
+ }
+
+ add(CharType::Raw, ch, 0);
+ }
+ }
+}}
+
+// json-cpp/details/string_parser.hpp end
+//----------------------------------------------------------------------
+
+namespace jsoncpp
+{
+ template
+ class Stream>>
+ {
+ public:
+ using this_type = Parser>;
+
+ explicit Stream(InputIterator first, InputIterator last)
+ : m_reader{first, last}
+ {
+ nextValue();
+ }
+
+ Type getType() const { return m_type; }
+ bool getBoolean() const { return m_boolean; }
+ double getNumber() const { return m_number; }
+ const std::string& getFieldName() const { return m_fieldName; }
+
+ void checkType(Type type) const
+ {
+ if (getType() != type)
+ throw makeError(ParserError::UnexpectedType);
+ }
+
+ bool isListEnd(char terminator)
+ {
+ eatWhitespace();
+ if (*m_reader != terminator)
+ return false;
+
+ ++m_reader;
+ return true;
+ }
+
+ void eatListSeparator()
+ {
+ eatWhitespace();
+ check(',');
+ eatWhitespace();
+ }
+
+ void nextNameValuePair()
+ {
+ eatWhitespace();
+ check('"');
+ parseString(m_fieldName);
+ eatWhitespace();
+ check(':');
+ nextValue();
+ }
+
+ void nextValue()
+ {
+ eatWhitespace();
+ m_type = nextValueImpl();
+ }
+
+ template
+ void parseString(std::basic_string& str)
+ {
+ auto err = parseStringImpl(m_reader, str);
+ if (err != ParserError::NoError)
+ throw m_reader.m_diag.makeError(err);
+ }
+
+ ParserError makeError(ParserError::Type type) const
+ {
+ return m_reader.m_diag.makeError(type);
+ }
+
+ private:
+ Type nextValueImpl()
+ {
+ switch (*m_reader)
+ {
+ case '{': ++m_reader; return Type::Object;
+ case '[': ++m_reader; return Type::Array;
+ case 't': ++m_reader; checkLiteral("true"); m_boolean = true; return Type::Boolean;
+ case 'f': ++m_reader; checkLiteral("false"); m_boolean = false; return Type::Boolean;
+ case 'n': ++m_reader; checkLiteral("null"); return Type::Null;
+ case '"': ++m_reader; return Type::String;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ m_number = parseRealNumber(m_reader);
+ return Type::Number;
+
+ case '-':
+ ++m_reader;
+ m_number = -parseRealNumber(m_reader);
+ return Type::Number;
+ }
+
+ throw unexpectedCharacter();
+ }
+
+ ParserError unexpectedCharacter() const
+ {
+ return makeError(ParserError::UnexpectedCharacter);
+ }
+
+ void check(char expectedChar)
+ {
+ if (*m_reader != expectedChar)
+ throw unexpectedCharacter();
+
+ ++m_reader;
+ }
+
+ template
+ void checkLiteral(const char(&literal)[N])
+ {
+ static_assert(N > 2, "");
+ for (auto i = 1; i != N - 1; ++i, ++m_reader)
+ if (*m_reader != literal[i])
+ throw unexpectedCharacter();
+ }
+
+ void eatWhitespace()
+ {
+ for (;; ++m_reader)
+ {
+ switch (*m_reader)
+ {
+ case '/':
+ ++m_reader;
+ check('/');
+ while (*m_reader != '\n')
+ ++m_reader;
+
+ // no break here
+ case '\n':
+ m_reader.m_diag.newLine();
+ break;
+
+ case ' ': case '\t': case '\r':
+ break;
+
+ default:
+ return;
+ }
+ }
+ }
+
+ details::Reader m_reader;
+
+ Type m_type;
+ double m_number;
+ bool m_boolean;
+ std::string m_fieldName;
+ };
+
+ template
+ inline void serialize(Parser& parser, bool& value)
+ {
+ parser.checkType(Type::Boolean);
+ value = parser.getBoolean();
+ }
+
+ template
+ inline typename std::enable_if::value>::type
+ serialize(Parser& parser, T& value)
+ {
+ parser.checkType(Type::Number);
+ auto number = parser.getNumber();
+ value = static_cast(number);
+ if (value != number)
+ throw parser.makeError(ParserError::NumberIsOutOfRange);
+ }
+
+ template
+ inline void serialize(Parser& parser, std::basic_string& value)
+ {
+ parser.checkType(Type::String);
+ parser.parseString(value);
+ }
+
+ namespace details
+ {
+ template
+ inline void parseList(Parser& parser, Type type, char terminator, Callback&& callback)
+ {
+ parser.checkType(type);
+
+ while (!parser.isListEnd(terminator))
+ {
+ callback();
+
+ if (parser.isListEnd(terminator))
+ return;
+
+ parser.eatListSeparator();
+ }
+ }
+ }
+
+ template
+ inline void parseObject(Parser& parser, Callback&& callback)
+ {
+ details::parseList(parser, Type::Object, '}', [&]
+ {
+ parser.nextNameValuePair();
+ callback(parser.getFieldName());
+ });
+ }
+
+ template
+ void parseArray(Parser& parser, Callback&& callback)
+ {
+ details::parseList(parser, Type::Array, ']', [&]
+ {
+ parser.nextValue();
+ callback();
+ });
+ }
+
+ template
+ inline void parse(T& object, InputIterator first, InputIterator last)
+ {
+ Parser> stream{first, last};
+ serialize(stream, object);
+ }
+
+ template
+ inline void parse(T& object, const CharT* str)
+ {
+ details::CStrIterator first{str}, last;
+ parse(object, first, last);
+ }
+
+ template
+ inline void parse(T& object, std::basic_string& str)
+ {
+ parse(object, std::begin(str), std::end(str));
+ }
+
+ template
+ inline void parse(T& object, std::basic_istream& stream)
+ {
+ std::istreambuf_iterator first{stream}, last;
+ parse(object, first, last);
+ }
+}
+
+// json-cpp/parse.hpp end
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// json-cpp/std_types.hpp begin
+
+#include
+#include
+#include
+#include