summaryrefslogtreecommitdiff
path: root/vendor/jsoncons-0.99.2/jsoncons/json.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/jsoncons-0.99.2/jsoncons/json.hpp')
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json.hpp3574
1 files changed, 0 insertions, 3574 deletions
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json.hpp b/vendor/jsoncons-0.99.2/jsoncons/json.hpp
deleted file mode 100644
index b9058b59..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json.hpp
+++ /dev/null
@@ -1,3574 +0,0 @@
-// Copyright 2013 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_HPP
-#define JSONCONS_JSON_HPP
-
-#include <limits>
-#include <string>
-#include <vector>
-#include <exception>
-#include <cstdlib>
-#include <cstring>
-#include <ostream>
-#include <memory>
-#include <typeinfo>
-#include "jsoncons/json_structures.hpp"
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_output_handler.hpp"
-#include "jsoncons/output_format.hpp"
-#include "jsoncons/json_serializer.hpp"
-#include "jsoncons/json_deserializer.hpp"
-#include "jsoncons/json_reader.hpp"
-#include "jsoncons/json_type_traits.hpp"
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wswitch"
-#endif
-
-namespace jsoncons {
-
-template <class T, class Alloc, typename... Args>
-T* create_impl(const Alloc& allocator, Args&& ... args)
-{
- typename std::allocator_traits<Alloc>:: template rebind_alloc<T> alloc(allocator);
- T* storage = alloc.allocate(1);
- try
- {
- std::allocator_traits<Alloc>:: template rebind_traits<T>::construct(alloc, storage, std::forward<Args>(args)...);
- }
- catch (...)
- {
- alloc.deallocate(storage,1);
- throw;
- }
- return storage;
-}
-
-template <class T, class Alloc>
-void destroy_impl(const Alloc& allocator, T* p)
-{
- typename std::allocator_traits<Alloc>:: template rebind_alloc<T> alloc(allocator);
- std::allocator_traits<Alloc>:: template rebind_traits<T>::destroy(alloc, p);
- alloc.deallocate(p,1);
-}
-
-template <typename CharT, class Alloc>
-class serializable_any
-{
-public:
- typedef Alloc allocator_type;
-
- serializable_any(const Alloc& allocator = Alloc())
- : impl_(nullptr)
- {
- (void)allocator;
- }
- serializable_any(const serializable_any& val)
- : allocator_(std::allocator_traits<allocator_type>::select_on_container_copy_construction(val.get_allocator()))
- {
- impl_ = val.impl_ != nullptr ? val.impl_->clone(allocator_) : nullptr;
- }
- serializable_any(const serializable_any& val, const Alloc& allocator)
- {
- (void)allocator;
- impl_ = val.impl_ != nullptr ? val.impl_->clone(Alloc()) : nullptr;
- }
-
- serializable_any(serializable_any&& val)
- : impl_(std::move(val.impl_))
- {
- val.impl_ = nullptr;
- }
- serializable_any(serializable_any&& val, const Alloc& allocator)
- : impl_(std::move(val.impl_))
- {
- (void)allocator;
- val.impl_ = nullptr;
- }
- ~serializable_any()
- {
- if (impl_ != nullptr)
- {
- destroy_impl(allocator_,impl_);
- }
- }
-
- template<typename T>
- explicit serializable_any(T val)
- {
- impl_ = create_impl<any_handle_impl<typename type_wrapper<T>::value_type>>(allocator_,val);
- }
-
- Alloc get_allocator() const
- {
- return allocator_;
- }
-
- template <typename T>
- typename type_wrapper<T>::reference cast()
- {
- if (typeid(*impl_) != typeid(any_handle_impl<typename type_wrapper<T>::value_type>))
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad serializable_any cast");
- }
- return static_cast<any_handle_impl<typename type_wrapper<T>::value_type>&>(*impl_).value_;
- }
-
- template <typename T>
- typename type_wrapper<T>::const_reference cast() const
- {
- if (typeid(*impl_) != typeid(any_handle_impl<typename type_wrapper<T>::value_type>))
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad serializable_any cast");
- }
- return static_cast<any_handle_impl<typename type_wrapper<T>::value_type>&>(*impl_).value_;
- }
-
- serializable_any& operator=(serializable_any rhs)
- {
- std::swap(impl_,rhs.impl_);
- return *this;
- }
-
- void to_stream(basic_json_output_handler<CharT>& os) const
- {
- impl_->to_stream(os);
- }
-
- class any_handle
- {
- public:
- virtual ~any_handle()
- {
- }
-
- virtual any_handle* clone(const Alloc& allocator) const = 0;
-
- virtual void to_stream(basic_json_output_handler<CharT>& os) const = 0;
- };
-
- template <class T>
- class any_handle_impl : public any_handle
- {
- public:
- any_handle_impl(T value, const Alloc& allocator = Alloc())
- : value_(value)
- {
- (void)allocator;
- }
-
- virtual any_handle* clone(const Alloc& allocator) const
- {
- return create_impl<any_handle_impl<T>>(allocator, value_);
- }
-
- virtual void to_stream(basic_json_output_handler<CharT>& os) const
- {
- serialize(os,value_);
- }
-
- T value_;
- };
-
- Alloc allocator_;
- any_handle* impl_;
-};
-
-template <typename CharT,class T> inline
-void serialize(basic_json_output_handler<CharT>& os, const T&)
-{
- os.value(null_type());
-}
-
-template <typename CharT>
-class basic_parse_error_handler;
-
-enum class value_types : uint8_t
-{
- // Simple types
- empty_object_t,
- small_string_t,
- double_t,
- integer_t,
- uinteger_t,
- bool_t,
- null_t,
- // Non simple types
- string_t,
- object_t,
- array_t,
- any_t
-};
-
-inline
-bool is_simple(value_types type)
-{
- return type < value_types::string_t;
-}
-
-template <typename CharT, typename Alloc = std::allocator<CharT>>
-class basic_json
-{
-public:
-
- typedef Alloc allocator_type;
-
- typedef CharT char_type;
- typedef typename std::char_traits<CharT> char_traits_type;
-
- typedef typename std::allocator_traits<Alloc>:: template rebind_alloc<CharT> string_allocator;
- typedef std::basic_string<CharT,char_traits_type,string_allocator> string_type;
- typedef basic_json<CharT,Alloc> value_type;
- typedef name_value_pair<string_type,value_type> member_type;
-
- typedef typename std::allocator_traits<Alloc>:: template rebind_alloc<basic_json<CharT,Alloc>> array_allocator;
-
- typedef typename std::allocator_traits<Alloc>:: template rebind_alloc<member_type> object_allocator;
-
- typedef json_array<basic_json<CharT,Alloc>,array_allocator> array;
- typedef json_object<string_type,basic_json<CharT,Alloc>,object_allocator> object;
- typedef serializable_any<char_type,Alloc> any;
-
- typedef jsoncons::null_type null_type;
-
- typedef typename object::iterator object_iterator;
- typedef typename object::const_iterator const_object_iterator;
- typedef typename array::iterator array_iterator;
- typedef typename array::const_iterator const_array_iterator;
-
- template <typename IteratorT>
- class range
- {
- IteratorT first_;
- IteratorT last_;
- public:
- range(const IteratorT& first, const IteratorT& last)
- : first_(first), last_(last)
- {
- }
-
- public:
- friend class basic_json<CharT, Alloc>;
-
- IteratorT begin()
- {
- return first_;
- }
- IteratorT end()
- {
- return last_;
- }
- };
-
- typedef range<object_iterator> object_range;
- typedef range<const_object_iterator> const_object_range;
- typedef range<array_iterator> array_range;
- typedef range<const_array_iterator> const_array_range;
-
- struct variant
- {
- struct string_data : public string_allocator
- {
- const char_type* c_str() const { return p_; }
- const char_type* data() const { return p_; }
- size_t length() const { return length_; }
- string_allocator get_allocator() const
- {
- return *this;
- }
-
- bool operator==(const string_data& rhs) const
- {
- return length() == rhs.length() ? std::char_traits<char_type>::compare(data(), rhs.data(), length()) == 0 : false;
- }
-
- string_data(const string_allocator& allocator)
- : string_allocator(allocator), p_(nullptr), length_(0)
- {
- }
-
- char_type* p_;
- size_t length_;
- private:
- string_data(const string_data&);
- string_data& operator=(const string_data&);
- };
-
- struct string_dataA
- {
- string_data data;
- char_type c[1];
- };
- typedef typename std::aligned_storage<sizeof(string_dataA), JSONCONS_ALIGNOF(string_dataA)>::type storage_type;
-
- static size_t aligned_size(size_t n)
- {
- return sizeof(storage_type) + n;
- }
-
- string_data* create_string_data(const char_type* s, size_t length, const string_allocator& allocator)
- {
- size_t mem_size = aligned_size(length*sizeof(char_type));
-
- typename std::allocator_traits<string_allocator>:: template rebind_alloc<char> alloc(allocator);
-
- char* storage = alloc.allocate(mem_size);
- string_data* ps = new(storage)string_data(allocator);
- auto psa = reinterpret_cast<string_dataA*>(storage);
-
- ps->p_ = new(&psa->c)char_type[length + 1];
- memcpy(ps->p_, s, length*sizeof(char_type));
- ps->p_[length] = 0;
- ps->length_ = length;
- return ps;
- }
-
- void destroy_string_data(const string_allocator& allocator, string_data* p)
- {
- size_t mem_size = aligned_size(p->length_*sizeof(char_type));
- typename std::allocator_traits<string_allocator>:: template rebind_alloc<char> alloc(allocator);
- alloc.deallocate(reinterpret_cast<char*>(p),mem_size);
- }
-
- static const size_t small_string_capacity = (sizeof(int64_t)/sizeof(char_type)) - 1;
-
- variant()
- : type_(value_types::empty_object_t)
- {
- }
-
- variant(const Alloc& a)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(a, object_allocator(a));
- }
-
- variant(std::initializer_list<value_type> init,
- const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, std::move(init), array_allocator(a));
- }
-
- explicit variant(variant&& var)
- : type_(value_types::null_t)
- {
- swap(var);
- }
-
- explicit variant(variant&& var, const Alloc& a)
- : type_(value_types::null_t)
- {
- swap(var);
- }
-
- explicit variant(const variant& var)
- {
- init_variant(var);
- }
- explicit variant(const variant& var, const Alloc& a)
- : type_(var.type_)
- {
- init_variant(var);
- }
-
- variant(const object & val)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(val.get_allocator(), val) ;
- }
-
- variant(const object & val, const Alloc& a)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(a, val, object_allocator(a)) ;
- }
-
- variant(object&& val)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(val.get_allocator(), std::move(val));
- }
-
- variant(object&& val, const Alloc& a)
- : type_(value_types::object_t)
- {
- value_.object_val_ = create_impl<object>(a, std::move(val), object_allocator(a));
- }
-
- variant(const array& val)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(val.get_allocator(), val);
- }
-
- variant(const array& val, const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, val, array_allocator(a));
- }
-
- variant(array&& val)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(val.get_allocator(), std::move(val));
- }
-
- variant(array&& val, const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, std::move(val), array_allocator(a));
- }
-
- explicit variant(const any& val, const Alloc& a)
- : type_(value_types::any_t)
- {
- value_.any_val_ = create_impl<any>(a, val);
- }
-
- explicit variant(null_type)
- : type_(value_types::null_t)
- {
- }
-
- explicit variant(bool val)
- : type_(value_types::bool_t)
- {
- value_.bool_val_ = val;
- }
-
- explicit variant(double val, uint8_t precision)
- : type_(value_types::double_t), length_or_precision_(precision)
- {
- value_.double_val_ = val;
- }
-
- explicit variant(int64_t val)
- : type_(value_types::integer_t)
- {
- value_.integer_val_ = val;
- }
-
- explicit variant(uint64_t val)
- : type_(value_types::uinteger_t)
- {
- value_.uinteger_val_ = val;
- }
-
- explicit variant(const string_type& s, const Alloc& a)
- {
- if (s.length() > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(a, s, string_allocator(a));
- value_.string_val_ = create_string_data(s.data(), s.length(), string_allocator(a));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(s.length());
- std::memcpy(value_.small_string_val_,s.data(),s.length()*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- explicit variant(const char_type* s, const Alloc& a)
- {
- size_t length = std::char_traits<char_type>::length(s);
- if (length > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(a, s, string_allocator(a));
- value_.string_val_ = create_string_data(s, length, string_allocator(a));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(length);
- std::memcpy(value_.small_string_val_,s,length*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- explicit variant(const char_type* s, size_t length, const Alloc& a)
- {
- if (length > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(a, s, length, string_allocator(a));
- value_.string_val_ = create_string_data(s, length, string_allocator(a));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(length);
- std::memcpy(value_.small_string_val_,s,length*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- template<class InputIterator>
- variant(InputIterator first, InputIterator last, const Alloc& a)
- : type_(value_types::array_t)
- {
- value_.array_val_ = create_impl<array>(a, first, last, array_allocator(a));
- }
-
- void init_variant(const variant& var)
- {
- type_ = var.type_;
- switch (type_)
- {
- case value_types::null_t:
- case value_types::empty_object_t:
- break;
- case value_types::double_t:
- length_or_precision_ = 0;
- value_.double_val_ = var.value_.double_val_;
- break;
- case value_types::integer_t:
- value_.integer_val_ = var.value_.integer_val_;
- break;
- case value_types::uinteger_t:
- value_.uinteger_val_ = var.value_.uinteger_val_;
- break;
- case value_types::bool_t:
- value_.bool_val_ = var.value_.bool_val_;
- break;
- case value_types::small_string_t:
- length_or_precision_ = var.length_or_precision_;
- std::memcpy(value_.small_string_val_,var.value_.small_string_val_,var.length_or_precision_*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- break;
- case value_types::string_t:
- //value_.string_val_ = create_impl<string_type>(var.value_.string_val_->get_allocator(), *(var.value_.string_val_), string_allocator(var.value_.string_val_->get_allocator()));
- value_.string_val_ = create_string_data(var.value_.string_val_->data(), var.value_.string_val_->length(), string_allocator(var.value_.string_val_->get_allocator()));
- break;
- case value_types::array_t:
- value_.array_val_ = create_impl<array>(var.value_.array_val_->get_allocator(), *(var.value_.array_val_), array_allocator(var.value_.array_val_->get_allocator()));
- break;
- case value_types::object_t:
- value_.object_val_ = create_impl<object>(var.value_.object_val_->get_allocator(), *(var.value_.object_val_), object_allocator(var.value_.object_val_->get_allocator()));
- break;
- case value_types::any_t:
- value_.any_val_ = create_impl<any>(var.value_.any_val_->get_allocator(), *(var.value_.any_val_));
- break;
- default:
- break;
- }
- }
-
- ~variant()
- {
- destroy_variant();
- }
-
- void destroy_variant()
- {
- switch (type_)
- {
- case value_types::string_t:
- //destroy_impl(value_.string_val_->get_allocator(), value_.string_val_);
- destroy_string_data(value_.string_val_->get_allocator(), value_.string_val_);
- break;
- case value_types::array_t:
- destroy_impl(value_.array_val_->get_allocator(), value_.array_val_);
- break;
- case value_types::object_t:
- destroy_impl(value_.object_val_->get_allocator(), value_.object_val_);
- break;
- case value_types::any_t:
- destroy_impl(value_.any_val_->get_allocator(), value_.any_val_);
- break;
- default:
- break;
- }
- }
-
- variant& operator=(const variant& val)
- {
- if (this != &val)
- {
- if (is_simple(type_))
- {
- if (is_simple(val.type_))
- {
- type_ = val.type_;
- length_or_precision_ = val.length_or_precision_;
- value_ = val.value_;
- }
- else
- {
- init_variant(val);
- }
- }
- else
- {
- destroy_variant();
- init_variant(val);
- }
- }
- return *this;
- }
-
- variant& operator=(variant&& val)
- {
- if (this != &val)
- {
- val.swap(*this);
- }
- return *this;
- }
-
- void assign(const object & val)
- {
- destroy_variant();
- type_ = value_types::object_t;
- value_.object_val_ = create_impl<object>(val.get_allocator(), val, object_allocator(val.get_allocator()));
- }
-
- void assign(object && val)
- {
- switch (type_)
- {
- case value_types::object_t:
- value_.object_val_->swap(val);
- break;
- default:
- destroy_variant();
- type_ = value_types::object_t;
- value_.object_val_ = create_impl<object>(val.get_allocator(), std::move(val), object_allocator(val.get_allocator()));
- break;
- }
- }
-
- void assign(const array& val)
- {
- destroy_variant();
- type_ = value_types::array_t;
- value_.array_val_ = create_impl<array>(val.get_allocator(), val, array_allocator(val.get_allocator())) ;
- }
-
- void assign(array&& val)
- {
- switch (type_)
- {
- case value_types::array_t:
- value_.array_val_->swap(val);
- break;
- default:
- destroy_variant();
- type_ = value_types::array_t;
- value_.array_val_ = create_impl<array>(val.get_allocator(), std::move(val), array_allocator(val.get_allocator()));
- break;
- }
- }
-
- void assign(const string_type& s)
- {
- destroy_variant();
- if (s.length() > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(s.get_allocator(), s, string_allocator(s.get_allocator()));
- value_.string_val_ = create_string_data(s.data(), s.length(), string_allocator(s.get_allocator()));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(s.length());
- std::memcpy(value_.small_string_val_,s.data(),s.length()*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- void assign_string(const char_type* s, size_t length, const Alloc& allocator = Alloc())
- {
- destroy_variant();
- if (length > variant::small_string_capacity)
- {
- type_ = value_types::string_t;
- //value_.string_val_ = create_impl<string_type>(allocator, s, length, string_allocator(allocator));
- value_.string_val_ = create_string_data(s, length, string_allocator(allocator));
- }
- else
- {
- type_ = value_types::small_string_t;
- length_or_precision_ = static_cast<uint8_t>(length);
- std::memcpy(value_.small_string_val_,s,length*sizeof(char_type));
- value_.small_string_val_[length_or_precision_] = 0;
- }
- }
-
- void assign(int64_t val)
- {
- destroy_variant();
- type_ = value_types::integer_t;
- value_.integer_val_ = val;
- }
-
- void assign(uint64_t val)
- {
- destroy_variant();
- type_ = value_types::uinteger_t;
- value_.uinteger_val_ = val;
- }
-
- void assign(double val, uint8_t precision = 0)
- {
- destroy_variant();
- type_ = value_types::double_t;
- length_or_precision_ = precision;
- value_.double_val_ = val;
- }
-
- void assign(bool val)
- {
- destroy_variant();
- type_ = value_types::bool_t;
- value_.bool_val_ = val;
- }
-
- void assign(null_type)
- {
- destroy_variant();
- type_ = value_types::null_t;
- }
-
- void assign(const any& rhs)
- {
- destroy_variant();
- type_ = value_types::any_t;
- value_.any_val_ = create_impl<any>(rhs.get_allocator(), rhs);
- }
-
- bool operator!=(const variant& rhs) const
- {
- return !(*this == rhs);
- }
-
- bool operator==(const variant& rhs) const
- {
- if (is_number() & rhs.is_number())
- {
- switch (type_)
- {
- case value_types::integer_t:
- switch (rhs.type_)
- {
- case value_types::integer_t:
- return value_.integer_val_ == rhs.value_.integer_val_;
- case value_types::uinteger_t:
- return value_.integer_val_ == rhs.value_.uinteger_val_;
- case value_types::double_t:
- return value_.integer_val_ == rhs.value_.double_val_;
- default:
- break;
- }
- break;
- case value_types::uinteger_t:
- switch (rhs.type_)
- {
- case value_types::integer_t:
- return value_.uinteger_val_ == rhs.value_.integer_val_;
- case value_types::uinteger_t:
- return value_.uinteger_val_ == rhs.value_.uinteger_val_;
- case value_types::double_t:
- return value_.uinteger_val_ == rhs.value_.double_val_;
- default:
- break;
- }
- break;
- case value_types::double_t:
- switch (rhs.type_)
- {
- case value_types::integer_t:
- return value_.double_val_ == rhs.value_.integer_val_;
- case value_types::uinteger_t:
- return value_.double_val_ == rhs.value_.uinteger_val_;
- case value_types::double_t:
- return value_.double_val_ == rhs.value_.double_val_;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
-
- switch (type_)
- {
- case value_types::bool_t:
- return type_ == rhs.type_ && value_.bool_val_ == rhs.value_.bool_val_;
- case value_types::null_t:
- return type_ == rhs.type_;
- case value_types::empty_object_t:
- return type_ == rhs.type_ || (rhs.type_ == value_types::object_t && rhs.empty());
- case value_types::small_string_t:
- return type_ == rhs.type_ && length_or_precision_ == rhs.length_or_precision_ ? std::char_traits<char_type>::compare(value_.small_string_val_,rhs.value_.small_string_val_,length_or_precision_) == 0 : false;
- case value_types::string_t:
- return type_ == rhs.type_ && *(value_.string_val_) == *(rhs.value_.string_val_);
- case value_types::array_t:
- return type_ == rhs.type_ && *(value_.array_val_) == *(rhs.value_.array_val_);
- break;
- case value_types::object_t:
- return (type_ == rhs.type_ && *(value_.object_val_) == *(rhs.value_.object_val_)) || (rhs.type_ == value_types::empty_object_t && empty());
- break;
- case value_types::any_t:
- return type_ == rhs.type_;
- default:
- // throw
- break;
- }
- return false;
- }
-
- bool is_null() const JSONCONS_NOEXCEPT
- {
- return type_ == value_types::null_t;
- }
-
- bool is_bool() const JSONCONS_NOEXCEPT
- {
- return type_ == value_types::bool_t;
- }
-
- bool empty() const JSONCONS_NOEXCEPT
- {
- switch (type_)
- {
- case value_types::small_string_t:
- return length_or_precision_ == 0;
- case value_types::string_t:
- return value_.string_val_->length() == 0;
- case value_types::array_t:
- return value_.array_val_->size() == 0;
- case value_types::empty_object_t:
- return true;
- case value_types::object_t:
- return value_.object_val_->size() == 0;
- default:
- return false;
- }
- }
-
- bool is_string() const JSONCONS_NOEXCEPT
- {
- return (type_ == value_types::string_t) | (type_ == value_types::small_string_t);
- }
-
- bool is_number() const JSONCONS_NOEXCEPT
- {
- return type_ == value_types::double_t || type_ == value_types::integer_t || type_ == value_types::uinteger_t;
- }
-
- void swap(variant& rhs)
- {
- using std::swap;
- if (this == &rhs)
- {
- // same object, do nothing
- }
- else
- {
- swap(type_, rhs.type_);
- swap(length_or_precision_, rhs.length_or_precision_);
- swap(value_, rhs.value_);
- }
- }
-
- value_types type_;
- uint8_t length_or_precision_;
- union
- {
- double double_val_;
- int64_t integer_val_;
- uint64_t uinteger_val_;
- bool bool_val_;
- object* object_val_;
- array* array_val_;
- any* any_val_;
- string_data* string_val_;
- char_type small_string_val_[sizeof(int64_t)/sizeof(char_type)];
- } value_;
- };
-
- template <class ParentT>
- class json_proxy
- {
- private:
- typedef json_proxy<ParentT> proxy_type;
-
- ParentT& parent_;
- const string_type& name_;
-
- json_proxy() = delete;
- json_proxy& operator = (const json_proxy& other) = delete;
-
- json_proxy(ParentT& parent, const string_type& name)
- : parent_(parent), name_(name)
- {
- }
-
- basic_json<CharT,Alloc>& evaluate()
- {
- return parent_.evaluate(name_);
- }
-
- const basic_json<CharT,Alloc>& evaluate() const
- {
- return parent_.evaluate(name_);
- }
-
- basic_json<CharT,Alloc>& evaluate_with_default()
- {
- basic_json<CharT,Alloc>& val = parent_.evaluate_with_default();
- auto it = val.find(name_.data(),name_.length());
- if (it == val.members().end())
- {
- it = val.set(val.members().begin(),name_,object(val.object_value().get_allocator()));
- }
- return it->value();
- }
-
- basic_json<CharT,Alloc>& evaluate(size_t index)
- {
- return parent_.evaluate(name_).at(index);
- }
-
- const basic_json<CharT,Alloc>& evaluate(size_t index) const
- {
- return parent_.evaluate(name_).at(index);
- }
-
- basic_json<CharT,Alloc>& evaluate(const string_type& index)
- {
- return parent_.evaluate(name_).at(index);
- }
-
- const basic_json<CharT,Alloc>& evaluate(const string_type& index) const
- {
- return parent_.evaluate(name_).at(index);
- }
- public:
-
- friend class basic_json<CharT,Alloc>;
-
- object_range members()
- {
- return evaluate().members();
- }
-
- const_object_range members() const
- {
- return evaluate().members();
- }
-
- array_range elements()
- {
- return evaluate().elements();
- }
-
- const_array_range elements() const
- {
- return evaluate().elements();
- }
-
- size_t size() const JSONCONS_NOEXCEPT
- {
- return evaluate().size();
- }
-
- value_types type() const
- {
- return evaluate().type();
- }
-
- size_t count(const string_type& name) const
- {
- return evaluate().count(name);
- }
-
- bool is_null() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_null();
- }
-
- bool empty() const
- {
- return evaluate().empty();
- }
-
- size_t capacity() const
- {
- return evaluate().capacity();
- }
-
- void reserve(size_t n)
- {
- evaluate().reserve(n);
- }
-
- void resize(size_t n)
- {
- evaluate().resize(n);
- }
-
- template <typename T>
- void resize(size_t n, T val)
- {
- evaluate().resize(n,val);
- }
-
- template<typename T>
- bool is() const
- {
- return evaluate().template is<T>();
- }
-
- bool is_string() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_string();
- }
-
- bool is_number() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_number();
- }
- bool is_bool() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_bool();
- }
-
- bool is_object() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_object();
- }
-
- bool is_array() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_array();
- }
-
- bool is_any() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_any();
- }
-
- bool is_integer() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_integer();
- }
-
- bool is_uinteger() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_uinteger();
- }
-
- bool is_double() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_double();
- }
-
- string_type as_string() const JSONCONS_NOEXCEPT
- {
- return evaluate().as_string();
- }
-
- string_type as_string(const string_allocator& allocator) const JSONCONS_NOEXCEPT
- {
- return evaluate().as_string(allocator);
- }
-
- string_type as_string(const basic_output_format<char_type>& format) const
- {
- return evaluate().as_string(format);
- }
-
- string_type as_string(const basic_output_format<char_type>& format,
- const string_allocator& allocator) const
- {
- return evaluate().as_string(format,allocator);
- }
-
- template<typename T>
- T as() const
- {
- return evaluate().template as<T>();
- }
-
- template<typename T>
- typename std::enable_if<std::is_same<string_type,T>::value>::type as(const string_allocator& allocator) const
- {
- return evaluate().template as<T>(allocator);
- }
-
- any& any_value()
- {
- return evaluate().any_value();
- }
-
- const any& any_value() const
- {
- return evaluate().any_value();
- }
-
- bool as_bool() const JSONCONS_NOEXCEPT
- {
- return evaluate().as_bool();
- }
-
- template <class T>
- std::vector<T> as_vector() const
- {
- return evaluate().template as_vector<T>();
- }
-
- double as_double() const
- {
- return evaluate().as_double();
- }
-
- int64_t as_integer() const
- {
- return evaluate().as_integer();
- }
-
- unsigned long long as_ulonglong() const
- {
- return evaluate().as_ulonglong();
- }
-
- uint64_t as_uinteger() const
- {
- return evaluate().as_uinteger();
- }
-
- template <class T>
- const T& any_cast() const
- {
- return evaluate().template any_cast<T>();
- }
- // Returns a const reference to the custom data associated with name
-
- template <class T>
- T& any_cast()
- {
- return evaluate().template any_cast<T>();
- }
- // Returns a reference to the custom data associated with name
-
- operator basic_json&()
- {
- return evaluate();
- }
-
- operator const basic_json&() const
- {
- return evaluate();
- }
-
- template <typename T>
- json_proxy& operator=(T val)
- {
- parent_.evaluate_with_default().set(name_, val);
- return *this;
- }
-
- json_proxy& operator=(const basic_json& val)
- {
- parent_.evaluate_with_default().set(name_, val);
- return *this;
- }
-
- json_proxy& operator=(basic_json&& val)
- {
- parent_.evaluate_with_default().set(name_, std::move(val));
- return *this;
- }
-
- bool operator==(const basic_json& val) const
- {
- return evaluate() == val;
- }
-
- bool operator!=(const basic_json& val) const
- {
- return evaluate() != val;
- }
-
- basic_json<CharT,Alloc>& operator[](size_t i)
- {
- return evaluate_with_default().at(i);
- }
-
- const basic_json<CharT,Alloc>& operator[](size_t i) const
- {
- return evaluate().at(i);
- }
-
- json_proxy<proxy_type> operator[](const string_type& name)
- {
- return json_proxy<proxy_type>(*this,name);
- }
-
- const json_proxy<proxy_type> operator[](const string_type& name) const
- {
- return json_proxy<proxy_type>(*this,name);
- }
-
- basic_json<CharT,Alloc>& at(const string_type& name)
- {
- return evaluate().at(name);
- }
-
- const basic_json<CharT,Alloc>& at(const string_type& name) const
- {
- return evaluate().at(name);
- }
-
- const basic_json<CharT,Alloc>& at(size_t index)
- {
- return evaluate().at(index);
- }
-
- const basic_json<CharT,Alloc>& at(size_t index) const
- {
- return evaluate().at(index);
- }
-
- object_iterator find(const string_type& name)
- {
- return evaluate().find(name);
- }
-
- const_object_iterator find(const string_type& name) const
- {
- return evaluate().find(name);
- }
-
- object_iterator find(const char_type* name)
- {
- return evaluate().find(name);
- }
-
- const_object_iterator find(const char_type* name) const
- {
- return evaluate().find(name);
- }
-
- object_iterator find(const char_type* name, size_t length)
- {
- return evaluate().find(name,length);
- }
-
- const_object_iterator find(const char_type* name, size_t length) const
- {
- return evaluate().find(name,length);
- }
-
- template <typename T>
- basic_json<CharT,Alloc> get(const string_type& name, T&& default_val) const
- {
- return evaluate().get(name,std::forward<T>(default_val));
- }
-
- void shrink_to_fit()
- {
- evaluate_with_default().shrink_to_fit();
- }
-
- void clear()
- {
- evaluate().clear();
- }
- // Remove all elements from an array or object
-
- void erase(object_iterator first, object_iterator last)
- {
- evaluate().erase(first, last);
- }
- // Remove a range of elements from an object
-
- void erase(array_iterator first, array_iterator last)
- {
- evaluate().erase(first, last);
- }
-
- void erase(const string_type& name)
- {
- evaluate().erase(name);
- }
-
- // Remove a member from an object
-
- void set(const string_type& name, const basic_json<CharT,Alloc>& value)
- {
- evaluate().set(name,value);
- }
-
- void set(string_type&& name, const basic_json<CharT,Alloc>& value)
-
- {
- evaluate().set(std::move(name),value);
- }
-
- void set(const string_type& name, basic_json<CharT,Alloc>&& value)
-
- {
- evaluate().set(name,std::move(value));
- }
-
- void set(string_type&& name, basic_json<CharT,Alloc>&& value)
-
- {
- evaluate().set(std::move(name),std::move(value));
- }
-
- object_iterator set(object_iterator hint, const string_type& name, const basic_json<CharT,Alloc>& value)
- {
- return evaluate().set(hint, name,value);
- }
-
- object_iterator set(object_iterator hint, string_type&& name, const basic_json<CharT,Alloc>& value)
-
- {
- return evaluate().set(hint, std::move(name),value);
- }
-
- object_iterator set(object_iterator hint, const string_type& name, basic_json<CharT,Alloc>&& value)
-
- {
- return evaluate().set(hint, name,std::move(value));
- }
-
- object_iterator set(object_iterator hint, string_type&& name, basic_json<CharT,Alloc>&& value)
-
- {
- return evaluate().set(hint, std::move(name),std::move(value));
- }
-
- void add(basic_json<CharT,Alloc>&& value)
- {
- evaluate_with_default().add(std::move(value));
- }
-
- void add(const basic_json<CharT,Alloc>& value)
- {
- evaluate_with_default().add(value);
- }
-
- array_iterator add(const_array_iterator pos, const basic_json<CharT,Alloc>& value)
- {
- return evaluate_with_default().add(pos, value);
- }
-
- array_iterator add(const_array_iterator pos, basic_json<CharT,Alloc>&& value)
- {
- return evaluate_with_default().add(pos, std::move(value));
- }
-
- string_type to_string(const string_allocator& allocator = string_allocator()) const JSONCONS_NOEXCEPT
- {
- return evaluate().to_string(allocator);
- }
-
- string_type to_string(const basic_output_format<char_type>& format, string_allocator& allocator = string_allocator()) const
- {
- return evaluate().to_string(format,allocator);
- }
-
- void to_stream(std::basic_ostream<char_type>& os) const
- {
- evaluate().to_stream(os);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format) const
- {
- evaluate().to_stream(os,format);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format, bool indenting) const
- {
- evaluate().to_stream(os,format,indenting);
- }
-
- void swap(basic_json<CharT,Alloc>& val)
- {
- evaluate_with_default().swap(val);
- }
-
- friend std::basic_ostream<char_type>& operator<<(std::basic_ostream<char_type>& os, const json_proxy& o)
- {
- o.to_stream(os);
- return os;
- }
-
-#if !defined(JSONCONS_NO_DEPRECATED)
-
- void resize_array(size_t n)
- {
- evaluate().resize_array(n);
- }
-
- template <typename T>
- void resize_array(size_t n, T val)
- {
- evaluate().resize_array(n,val);
- }
-
- object_iterator begin_members()
- {
- return evaluate().begin_members();
- }
-
- const_object_iterator begin_members() const
- {
- return evaluate().begin_members();
- }
-
- object_iterator end_members()
- {
- return evaluate().end_members();
- }
-
- const_object_iterator end_members() const
- {
- return evaluate().end_members();
- }
-
- array_iterator begin_elements()
- {
- return evaluate().begin_elements();
- }
-
- const_array_iterator begin_elements() const
- {
- return evaluate().begin_elements();
- }
-
- array_iterator end_elements()
- {
- return evaluate().end_elements();
- }
-
- const_array_iterator end_elements() const
- {
- return evaluate().end_elements();
- }
-
- const basic_json<CharT,Alloc>& get(const string_type& name) const
- {
- return evaluate().get(name);
- }
-
- bool is_ulonglong() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_ulonglong();
- }
-
- bool is_longlong() const JSONCONS_NOEXCEPT
- {
- return evaluate().is_longlong();
- }
-
- int as_int() const
- {
- return evaluate().as_int();
- }
-
- unsigned int as_uint() const
- {
- return evaluate().as_uint();
- }
-
- long as_long() const
- {
- return evaluate().as_long();
- }
-
- unsigned long as_ulong() const
- {
- return evaluate().as_ulong();
- }
-
- long long as_longlong() const
- {
- return evaluate().as_longlong();
- }
-
- void add(size_t index, const basic_json<CharT,Alloc>& value)
- {
- evaluate_with_default().add(index, value);
- }
-
- void add(size_t index, basic_json<CharT,Alloc>&& value)
- {
- evaluate_with_default().add(index, std::move(value));
- }
-
- bool has_member(const string_type& name) const
- {
- return evaluate().has_member(name);
- }
-
- // Remove a range of elements from an array
- void remove_range(size_t from_index, size_t to_index)
- {
- evaluate().remove_range(from_index, to_index);
- }
- // Remove a range of elements from an array
- void remove(const string_type& name)
- {
- evaluate().remove(name);
- }
- void remove_member(const string_type& name)
- {
- evaluate().remove(name);
- }
- bool is_empty() const JSONCONS_NOEXCEPT
- {
- return empty();
- }
- bool is_numeric() const JSONCONS_NOEXCEPT
- {
- return is_number();
- }
-#endif
- };
-
- static basic_json parse_stream(std::basic_istream<char_type>& is);
- static basic_json parse_stream(std::basic_istream<char_type>& is, basic_parse_error_handler<char_type>& err_handler);
-
- static basic_json parse(const string_type& s)
- {
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_parser<char_type> parser(handler);
- parser.begin_parse();
- parser.parse(s.data(),0,s.length());
- parser.end_parse();
- parser.check_done(s.data(),parser.index(),s.length());
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json string");
- }
- return handler.get_result();
- }
-
- static basic_json parse(const string_type& s, basic_parse_error_handler<char_type>& err_handler)
- {
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_parser<char_type> parser(handler,err_handler);
- parser.begin_parse();
- parser.parse(s.data(),0,s.length());
- parser.end_parse();
- parser.check_done(s.data(),parser.index(),s.length());
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json string");
- }
- return handler.get_result();
- }
-
- static basic_json parse_file(const std::string& s);
-
- static basic_json parse_file(const std::string& s, basic_parse_error_handler<char_type>& err_handler);
-
- static basic_json make_array()
- {
- return basic_json::array();
- }
-
- static basic_json make_array(size_t n, const array_allocator& allocator = array_allocator())
- {
- return basic_json::array(n,allocator);
- }
-
- template <class T>
- static basic_json make_array(size_t n, const T& val, const array_allocator& allocator = array_allocator())
- {
- return basic_json::array(n, val,allocator);
- }
-
- template <size_t dim>
- static typename std::enable_if<dim==1,basic_json>::type make_array(size_t n)
- {
- return array(n);
- }
-
- template <size_t dim, class T>
- static typename std::enable_if<dim==1,basic_json>::type make_array(size_t n, const T& val, const Alloc& allocator = Alloc())
- {
- return array(n,val,allocator);
- }
-
- template <size_t dim, typename... Args>
- static typename std::enable_if<(dim>1),basic_json>::type make_array(size_t n, Args... args)
- {
- const size_t dim1 = dim - 1;
-
- basic_json val = make_array<dim1>(args...);
- val.resize(n);
- for (size_t i = 0; i < n; ++i)
- {
- val[i] = make_array<dim1>(args...);
- }
- return val;
- }
-
- variant var_;
-
- basic_json()
- : var_()
- {
- }
-
- basic_json(const Alloc& allocator)
- : var_(allocator)
- {
- }
-
- basic_json(std::initializer_list<value_type> init,
- const Alloc& allocator = Alloc())
- : var_(std::move(init), allocator)
- {
- }
-
- basic_json(const basic_json<CharT, Alloc>& val)
- : var_(val.var_)
- {
- }
-
- basic_json(const basic_json<CharT, Alloc>& val, const Alloc& allocator)
- : var_(val.var_,allocator)
- {
- }
-
- basic_json(basic_json<CharT,Alloc>&& other)
- : var_(std::move(other.var_))
- {
- }
-
- basic_json(basic_json<CharT,Alloc>&& other, const Alloc& allocator)
- : var_(std::move(other.var_),allocator)
- {
- }
-
- basic_json(const array& val)
- : var_(val)
- {
- }
-
- basic_json(array&& other)
- : var_(std::move(other))
- {
- }
-
- basic_json(const object& other)
- : var_(other)
- {
- }
-
- basic_json(object&& other)
- : var_(std::move(other))
- {
- }
-
- template <class ParentT>
- basic_json(const json_proxy<ParentT>& proxy, const Alloc& allocator = Alloc())
- : var_(proxy.evaluate().var_,allocator)
- {
- }
-
- template <typename T>
- basic_json(T val)
- : var_(null_type())
- {
- json_type_traits<value_type,T>::assign(*this,val);
- }
-
- basic_json(double val, uint8_t precision)
- : var_(val,precision)
- {
- }
-
- template <typename T>
- basic_json(T val, const Alloc& allocator)
- : var_(allocator)
- {
- json_type_traits<value_type,T>::assign(*this,val);
- }
-
- basic_json(const char_type *s, size_t length, const Alloc& allocator = Alloc())
- : var_(s, length, allocator)
- {
- }
- template<class InputIterator>
- basic_json(InputIterator first, InputIterator last, const Alloc& allocator = Alloc())
- : var_(first,last,allocator)
- {
- }
-
- ~basic_json()
- {
- }
-
- basic_json& operator=(const basic_json<CharT,Alloc>& rhs)
- {
- var_ = rhs.var_;
- return *this;
- }
-
- basic_json& operator=(basic_json<CharT,Alloc>&& rhs)
- {
- if (this != &rhs)
- {
- var_ = std::move(rhs.var_);
- }
- return *this;
- }
-
- basic_json& operator=(std::initializer_list<value_type> init)
- {
- basic_json<CharT,Alloc> val(init);
- swap(val);
- return *this;
- }
-
- template <class T>
- basic_json<CharT, Alloc>& operator=(T val)
- {
- json_type_traits<value_type,T>::assign(*this,val);
- return *this;
- }
-
- bool operator!=(const basic_json<CharT,Alloc>& rhs) const;
-
- bool operator==(const basic_json<CharT,Alloc>& rhs) const;
-
- size_t size() const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return 0;
- case value_types::object_t:
- return var_.value_.object_val_->size();
- case value_types::array_t:
- return var_.value_.array_val_->size();
- default:
- return 0;
- }
- }
-
- basic_json<CharT,Alloc>& operator[](size_t i)
- {
- return at(i);
- }
-
- const basic_json<CharT,Alloc>& operator[](size_t i) const
- {
- return at(i);
- }
-
- json_proxy<basic_json<CharT, Alloc>> operator[](const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return json_proxy<basic_json<CharT,Alloc>>(*this, name);
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- break;
- }
- }
-
- const basic_json<CharT,Alloc>& operator[](const string_type& name) const
- {
- return at(name);
- }
-
- string_type to_string(const string_allocator& allocator=string_allocator()) const JSONCONS_NOEXCEPT
- {
- string_type s(allocator);
- std::basic_ostringstream<char_type,char_traits_type,string_allocator> os(s);
- {
- basic_json_serializer<char_type> serializer(os);
- to_stream(serializer);
- }
- return os.str();
- }
-
- string_type to_string(const basic_output_format<char_type>& format,
- const string_allocator& allocator=string_allocator()) const
- {
- string_type s(allocator);
- std::basic_ostringstream<char_type> os(s);
- {
- basic_json_serializer<char_type> serializer(os, format);
- to_stream(serializer);
- }
- return os.str();
- }
-
- void to_stream(basic_json_output_handler<char_type>& handler) const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- handler.value(var_.value_.small_string_val_,var_.length_or_precision_);
- break;
- case value_types::string_t:
- handler.value(var_.value_.string_val_->data(),var_.value_.string_val_->length());
- break;
- case value_types::double_t:
- handler.value(var_.value_.double_val_, var_.length_or_precision_);
- break;
- case value_types::integer_t:
- handler.value(var_.value_.integer_val_);
- break;
- case value_types::uinteger_t:
- handler.value(var_.value_.uinteger_val_);
- break;
- case value_types::bool_t:
- handler.value(var_.value_.bool_val_);
- break;
- case value_types::null_t:
- handler.value(null_type());
- break;
- case value_types::empty_object_t:
- handler.begin_object();
- handler.end_object();
- break;
- case value_types::object_t:
- {
- handler.begin_object();
- object* o = var_.value_.object_val_;
- for (const_object_iterator it = o->begin(); it != o->end(); ++it)
- {
- handler.name((it->name()).data(),it->name().length());
- it->value().to_stream(handler);
- }
- handler.end_object();
- }
- break;
- case value_types::array_t:
- {
- handler.begin_array();
- array *o = var_.value_.array_val_;
- for (const_array_iterator it = o->begin(); it != o->end(); ++it)
- {
- it->to_stream(handler);
- }
- handler.end_array();
- }
- break;
- case value_types::any_t:
- var_.value_.any_val_->to_stream(handler);
- break;
- default:
- break;
- }
- }
-
- void to_stream(std::basic_ostream<char_type>& os) const
- {
- basic_json_serializer<char_type> serializer(os);
- to_stream(serializer);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format) const
- {
- basic_json_serializer<char_type> serializer(os, format);
- to_stream(serializer);
- }
-
- void to_stream(std::basic_ostream<char_type>& os, const basic_output_format<char_type>& format, bool indenting) const
- {
- basic_json_serializer<char_type> serializer(os, format, indenting);
- to_stream(serializer);
- }
-
- bool is_null() const JSONCONS_NOEXCEPT
- {
- return var_.is_null();
- }
-
- size_t count(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::object_t:
- {
- auto it = var_.value_.object_val_->find(name.data(),name.length());
- if (it == members().end())
- {
- return 0;
- }
- size_t count = 0;
- while (it != members().end() && it->name() == name)
- {
- ++count;
- ++it;
- }
- return count;
- }
- break;
- default:
- return 0;
- }
- }
-
- template<typename T>
- bool is() const
- {
- return json_type_traits<value_type,T>::is(*this);
- }
-
- bool is_string() const JSONCONS_NOEXCEPT
- {
- return var_.is_string();
- }
-
-
- bool is_bool() const JSONCONS_NOEXCEPT
- {
- return var_.is_bool();
- }
-
- bool is_object() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::object_t || var_.type_ == value_types::empty_object_t;
- }
-
- bool is_array() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::array_t;
- }
-
- bool is_any() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::any_t;
- }
-
- bool is_integer() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::integer_t || (var_.type_ == value_types::uinteger_t && (as_uinteger() <= static_cast<unsigned long long>(std::numeric_limits<long long>::max JSONCONS_NO_MACRO_EXP())));
- }
-
- bool is_uinteger() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::uinteger_t || (var_.type_ == value_types::integer_t && as_integer() >= 0);
- }
-
- bool is_double() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::double_t;
- }
-
- bool is_number() const JSONCONS_NOEXCEPT
- {
- return var_.is_number();
- }
-
- bool empty() const JSONCONS_NOEXCEPT
- {
- return var_.empty();
- }
-
- size_t capacity() const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return var_.value_.array_val_->capacity();
- case value_types::object_t:
- return var_.value_.object_val_->capacity();
- default:
- return 0;
- }
- }
-
- template<class U=Alloc,
- typename std::enable_if<std::is_default_constructible<U>::value
- >::type* = nullptr>
- void create_object_implicitly()
- {
- var_.type_ = value_types::object_t;
- var_.value_.object_val_ = create_impl<object>(Alloc(),object_allocator(Alloc()));
- }
-
- template<class U=Alloc,
- typename std::enable_if<!std::is_default_constructible<U>::value
- >::type* = nullptr>
- void create_object_implicitly() const
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Cannot create_impl object implicitly - allocator is not default constructible.");
- }
-
- void reserve(size_t n)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->reserve(n);
- break;
- case value_types::empty_object_t:
- {
- create_object_implicitly();
- var_.value_.object_val_->reserve(n);
- }
- break;
- case value_types::object_t:
- {
- var_.value_.object_val_->reserve(n);
- }
- break;
- default:
- break;
- }
- }
-
- void resize(size_t n)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->resize(n);
- break;
- default:
- break;
- }
- }
-
- template <typename T>
- void resize(size_t n, T val)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->resize(n, val);
- break;
- default:
- break;
- }
- }
-
- template<typename T>
- T as() const
- {
- return json_type_traits<value_type,T>::as(*this);
- }
-
- template<typename T>
- typename std::enable_if<std::is_same<string_type,T>::value>::type as(const string_allocator& allocator) const
- {
- return json_type_traits<value_type,T>::as(*this,allocator);
- }
-
- bool as_bool() const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::null_t:
- case value_types::empty_object_t:
- return false;
- case value_types::bool_t:
- return var_.value_.bool_val_;
- case value_types::double_t:
- return var_.value_.double_val_ != 0.0;
- case value_types::integer_t:
- return var_.value_.integer_val_ != 0;
- case value_types::uinteger_t:
- return var_.value_.uinteger_val_ != 0;
- case value_types::small_string_t:
- return var_.length_or_precision_ != 0;
- case value_types::string_t:
- return var_.value_.string_val_->length() != 0;
- case value_types::array_t:
- return var_.value_.array_val_->size() != 0;
- case value_types::object_t:
- return var_.value_.object_val_->size() != 0;
- case value_types::any_t:
- return true;
- default:
- return false;
- }
- }
-
- int64_t as_integer() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<int64_t>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<int64_t>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<int64_t>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an integer");
- }
- }
-
- uint64_t as_uinteger() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<uint64_t>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<uint64_t>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<uint64_t>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an unsigned integer");
- }
- }
-
- double as_double() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return var_.value_.double_val_;
- case value_types::integer_t:
- return static_cast<double>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<double>(var_.value_.uinteger_val_);
- case value_types::null_t:
- return std::numeric_limits<double>::quiet_NaN();
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not a double");
- }
- }
-
- string_type as_string() const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),var_.value_.string_val_->get_allocator());
- default:
- return to_string();
- }
- }
-
- string_type as_string(const string_allocator& allocator) const JSONCONS_NOEXCEPT
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_,allocator);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),allocator);
- default:
- return to_string(allocator);
- }
- }
-
- string_type as_string(const basic_output_format<char_type>& format) const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),var_.value_.string_val_->get_allocator());
- default:
- return to_string(format);
- }
- }
-
- string_type as_string(const basic_output_format<char_type>& format,
- const string_allocator& allocator) const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return string_type(var_.value_.small_string_val_,var_.length_or_precision_,allocator);
- case value_types::string_t:
- return string_type(var_.value_.string_val_->data(),var_.value_.string_val_->length(),allocator);
- default:
- return to_string(format,allocator);
- }
- }
-
- const char_type* as_cstring() const
- {
- switch (var_.type_)
- {
- case value_types::small_string_t:
- return var_.value_.small_string_val_;
- case value_types::string_t:
- return var_.value_.string_val_->c_str();
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not a cstring");
- }
- }
-
- any& any_value();
-
- const any& any_value() const;
-
- basic_json<CharT, Alloc>& at(const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range,"%s not found", name);
- case value_types::object_t:
- {
- auto it = var_.value_.object_val_->find(name.data(),name.length());
- if (it == members().end())
- {
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range, "%s not found", name);
- }
- return it->value();
- }
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- basic_json<CharT, Alloc>& evaluate()
- {
- return *this;
- }
-
- basic_json<CharT, Alloc>& evaluate_with_default()
- {
- return *this;
- }
-
- const basic_json<CharT, Alloc>& evaluate() const
- {
- return *this;
- }
-
- basic_json<CharT, Alloc>& evaluate(size_t i)
- {
- return at(i);
- }
-
- const basic_json<CharT, Alloc>& evaluate(size_t i) const
- {
- return at(i);
- }
-
- basic_json<CharT, Alloc>& evaluate(const string_type& name)
- {
- return at(name);
- }
-
- const basic_json<CharT, Alloc>& evaluate(const string_type& name) const
- {
- return at(name);
- }
-
- const basic_json<CharT, Alloc>& at(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range,"%s not found", name);
- case value_types::object_t:
- {
- auto it = var_.value_.object_val_->find(name.data(),name.length());
- if (it == members().end())
- {
- JSONCONS_THROW_EXCEPTION_1(std::out_of_range, "%s not found", name);
- }
- return it->value();
- }
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- basic_json<CharT, Alloc>& at(size_t i)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- if (i >= var_.value_.array_val_->size())
- {
- JSONCONS_THROW_EXCEPTION(std::out_of_range,"Invalid array subscript");
- }
- return var_.value_.array_val_->operator[](i);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Index on non-array value not supported");
- }
- }
-
- const basic_json<CharT, Alloc>& at(size_t i) const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- if (i >= var_.value_.array_val_->size())
- {
- JSONCONS_THROW_EXCEPTION(std::out_of_range,"Invalid array subscript");
- }
- return var_.value_.array_val_->operator[](i);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Index on non-array value not supported");
- }
- }
-
- object_iterator find(const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name.data(),name.length());
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- const_object_iterator find(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name.data(),name.length());
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- object_iterator find(const char_type* name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, std::char_traits<char_type>::length(name));
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- const_object_iterator find(const char_type* name) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, std::char_traits<char_type>::length(name));
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- object_iterator find(const char_type* name, size_t length)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, length);
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- const_object_iterator find(const char_type* name, size_t length) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return members().end();
- case value_types::object_t:
- return var_.value_.object_val_->find(name, length);
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- template<typename T>
- basic_json<CharT, Alloc> get(const string_type& name, T&& default_val) const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- {
- return basic_json<CharT,Alloc>(std::forward<T>(default_val));
- }
- case value_types::object_t:
- {
- const_object_iterator it = var_.value_.object_val_->find(name.data(),name.length());
- if (it != members().end())
- {
- return it->value();
- }
- else
- {
- return basic_json<CharT,Alloc>(std::forward<T>(default_val));
- }
- }
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- // Modifiers
-
- void shrink_to_fit()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->shrink_to_fit();
- break;
- case value_types::object_t:
- var_.value_.object_val_->shrink_to_fit();
- break;
- default:
- break;
- }
- }
-
- void clear()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->clear();
- break;
- case value_types::object_t:
- var_.value_.object_val_->clear();
- break;
- default:
- break;
- }
- }
-
- void erase(object_iterator first, object_iterator last)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- break;
- case value_types::object_t:
- var_.value_.object_val_->erase(first, last);
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- break;
- }
- }
-
- void erase(array_iterator first, array_iterator last)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->erase(first, last);
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an array");
- break;
- }
- }
-
- // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive.
-
- void erase(const string_type& name)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- break;
- case value_types::object_t:
- var_.value_.object_val_->erase(name.data(),name.length());
- break;
- default:
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object", name);
- break;
- }
- }
-
- void set(const string_type& name, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(name, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object", name);
- }
- }
- }
-
- void set(string_type&& name, const basic_json<CharT, Alloc>& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(std::move(name),value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- void set(const string_type& name, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(name,std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- void set(string_type&& name, basic_json<CharT, Alloc>&& value)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- var_.value_.object_val_->set(std::move(name),std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, const string_type& name, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, name, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object", name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, string_type&& name, const basic_json<CharT, Alloc>& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, std::move(name),value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, const string_type& name, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, name,std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- object_iterator set(object_iterator hint, string_type&& name, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return var_.value_.object_val_->set(hint, std::move(name),std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to set %s on a value that is not an object",name);
- }
- }
- }
-
- void add(const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->push_back(value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- void add(basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::array_t:
- var_.value_.array_val_->push_back(std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- array_iterator add(const_array_iterator pos, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return var_.value_.array_val_->add(pos, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- array_iterator add(const_array_iterator pos, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::array_t:
- return var_.value_.array_val_->add(pos, std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- value_types type() const
- {
- return var_.type_;
- }
-
- uint8_t length_or_precision() const
- {
- return var_.length_or_precision_;
- }
-
- void swap(basic_json<CharT,Alloc>& b)
- {
- var_.swap(b.var_);
- }
-
- template <class T>
- std::vector<T> as_vector() const
- {
- std::vector<T> v(size());
- for (size_t i = 0; i < v.size(); ++i)
- {
- v[i] = json_type_traits<value_type,T>::as(at(i));
- }
- return v;
- }
-
- friend void swap(basic_json<CharT,Alloc>& a, basic_json<CharT,Alloc>& b)
- {
- a.swap(b);
- }
-
- void assign_any(const typename basic_json<CharT,Alloc>::any& rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_string(const string_type& rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_string(const char_type* rhs, size_t length)
- {
- var_.assign_string(rhs,length);
- }
-
- void assign_bool(bool rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_object(const object & rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_array(const array& rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_null()
- {
- var_.assign(null_type());
- }
-
- template <typename T>
- const T& any_cast() const
- {
- if (var_.type_ != value_types::any_t)
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad any cast");
- }
- return var_.value_.any_val_->template cast<T>();
- }
- template <typename T>
- T& any_cast()
- {
- if (var_.type_ != value_types::any_t)
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad any cast");
- }
- return var_.value_.any_val_->template cast<T>();
- }
-
- void assign_integer(int64_t rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_uinteger(uint64_t rhs)
- {
- var_.assign(rhs);
- }
-
- void assign_double(double rhs, uint8_t precision = 0)
- {
- var_.assign(rhs,precision);
- }
-
- static basic_json make_2d_array(size_t m, size_t n);
-
- template <typename T>
- static basic_json make_2d_array(size_t m, size_t n, T val);
-
- static basic_json make_3d_array(size_t m, size_t n, size_t k);
-
- template <typename T>
- static basic_json make_3d_array(size_t m, size_t n, size_t k, T val);
-
-#if !defined(JSONCONS_NO_DEPRECATED)
- typedef any json_any_type;
-
- static basic_json parse(std::basic_istream<char_type>& is)
- {
- return parse_stream(is);
- }
- static basic_json parse(std::basic_istream<char_type>& is, basic_parse_error_handler<char_type>& err_handler)
- {
- return parse_stream(is,err_handler);
- }
-
- static basic_json parse_string(const string_type& s)
- {
- return parse(s);
- }
-
- static basic_json parse_string(const string_type& s, basic_parse_error_handler<char_type>& err_handler)
- {
- return parse(s,err_handler);
- }
-
- void resize_array(size_t n)
- {
- resize(n);
- }
-
- template <typename T>
- void resize_array(size_t n, T val)
- {
- resize(n,val);
- }
-
- object_iterator begin_members()
- {
- return members().begin();
- }
-
- const_object_iterator begin_members() const
- {
- return members().begin();
- }
-
- object_iterator end_members()
- {
- return members().end();
- }
-
- const_object_iterator end_members() const
- {
- return members().end();
- }
-
- array_iterator begin_elements()
- {
- return elements().begin();
- }
-
- const_array_iterator begin_elements() const
- {
- return elements().begin();
- }
-
- array_iterator end_elements()
- {
- return elements().end();
- }
-
- const_array_iterator end_elements() const
- {
- return elements().end();
- }
-
- const basic_json<CharT,Alloc>& get(const string_type& name) const
- {
- static const basic_json<CharT, Alloc> a_null = null_type();
-
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return a_null;
- case value_types::object_t:
- {
- const_object_iterator it = var_.value_.object_val_->find(name.data(),name.length());
- return it != members().end() ? it->value() : a_null;
- }
- default:
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Attempting to get %s from a value that is not an object", name);
- }
- }
- }
-
- bool is_longlong() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::integer_t;
- }
-
- bool is_ulonglong() const JSONCONS_NOEXCEPT
- {
- return var_.type_ == value_types::uinteger_t;
- }
-
- long long as_longlong() const
- {
- return as_integer();
- }
-
- unsigned long long as_ulonglong() const
- {
- return as_uinteger();
- }
-
- int as_int() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<int>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<int>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<int>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an int");
- }
- }
-
- unsigned int as_uint() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<unsigned int>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<unsigned int>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<unsigned int>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an unsigned int");
- }
- }
-
- long as_long() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<long>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<long>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<long>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not a long");
- }
- }
-
- unsigned long as_ulong() const
- {
- switch (var_.type_)
- {
- case value_types::double_t:
- return static_cast<unsigned long>(var_.value_.double_val_);
- case value_types::integer_t:
- return static_cast<unsigned long>(var_.value_.integer_val_);
- case value_types::uinteger_t:
- return static_cast<unsigned long>(var_.value_.uinteger_val_);
- case value_types::bool_t:
- return var_.value_.bool_val_ ? 1 : 0;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an unsigned long");
- }
- }
-
- void add(size_t index, const basic_json<CharT, Alloc>& value)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->add(index, value);
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- void add(size_t index, basic_json<CharT, Alloc>&& value){
- switch (var_.type_){
- case value_types::array_t:
- var_.value_.array_val_->add(index, std::move(value));
- break;
- default:
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Attempting to insert into a value that is not an array");
- }
- }
- }
-
- bool has_member(const string_type& name) const
- {
- switch (var_.type_)
- {
- case value_types::object_t:
- {
- const_object_iterator it = var_.value_.object_val_->find(name.data(),name.length());
- return it != members().end();
- }
- break;
- default:
- return false;
- }
- }
-
- void remove_range(size_t from_index, size_t to_index)
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- var_.value_.array_val_->remove_range(from_index, to_index);
- break;
- default:
- break;
- }
- }
- // Removes all elements from an array value whose index is between from_index, inclusive, and to_index, exclusive.
-
- void remove(const string_type& name)
- {
- erase(name.data(),name.length());
- }
- void remove_member(const string_type& name)
- {
- erase(name.data(),name.length());
- }
- // Removes a member from an object value
-
- bool is_empty() const JSONCONS_NOEXCEPT
- {
- return empty();
- }
- bool is_numeric() const JSONCONS_NOEXCEPT
- {
- return is_number();
- }
-
- void assign_longlong(long long rhs)
- {
- var_.assign(rhs);
- }
- void assign_ulonglong(unsigned long long rhs)
- {
- var_.assign(rhs);
- }
-
- template<int size>
- static typename std::enable_if<size==1,basic_json>::type make_multi_array()
- {
- return make_array();
- }
- template<size_t size>
- static typename std::enable_if<size==1,basic_json>::type make_multi_array(size_t n)
- {
- return make_array(n);
- }
- template<size_t size,typename T>
- static typename std::enable_if<size==1,basic_json>::type make_multi_array(size_t n, T val)
- {
- return make_array(n,val);
- }
- template<size_t size>
- static typename std::enable_if<size==2,basic_json>::type make_multi_array(size_t m, size_t n)
- {
- return make_array<2>(m, n);
- }
- template<size_t size,typename T>
- static typename std::enable_if<size==2,basic_json>::type make_multi_array(size_t m, size_t n, T val)
- {
- return make_array<2>(m, n, val);
- }
- template<size_t size>
- static typename std::enable_if<size==3,basic_json>::type make_multi_array(size_t m, size_t n, size_t k)
- {
- return make_array<3>(m, n, k);
- }
- template<size_t size,typename T>
- static typename std::enable_if<size==3,basic_json>::type make_multi_array(size_t m, size_t n, size_t k, T val)
- {
- return make_array<3>(m, n, k, val);
- }
-#endif
-
- object_range members()
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return object_range(object_iterator(true),object_iterator(true));
- case value_types::object_t:
- return object_range(object_value().begin(),object_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- }
- }
-
- const_object_range members() const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- return const_object_range(const_object_iterator(true),const_object_iterator(true));
- case value_types::object_t:
- return const_object_range(object_value().begin(),object_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an object");
- }
- }
-
- array_range elements()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return array_range(array_value().begin(),array_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an array");
- }
- }
-
- const_array_range elements() const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return const_array_range(array_value().begin(),array_value().end());
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an array");
- }
- }
-
- array& array_value()
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return *(var_.value_.array_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad array cast");
- break;
- }
- }
-
- const array& array_value() const
- {
- switch (var_.type_)
- {
- case value_types::array_t:
- return *(var_.value_.array_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad array cast");
- break;
- }
- }
-
- object& object_value()
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- create_object_implicitly();
- case value_types::object_t:
- return *(var_.value_.object_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad object cast");
- break;
- }
- }
-
- const object& object_value() const
- {
- switch (var_.type_)
- {
- case value_types::empty_object_t:
- const_cast<value_type*>(this)->create_object_implicitly(); // HERE
- case value_types::object_t:
- return *(var_.value_.object_val_);
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad object cast");
- break;
- }
- }
-
-private:
-
- friend std::basic_ostream<typename string_type::value_type>& operator<<(std::basic_ostream<typename string_type::value_type>& os, const basic_json<CharT, Alloc>& o)
- {
- o.to_stream(os);
- return os;
- }
-
- friend std::basic_istream<typename string_type::value_type>& operator<<(std::basic_istream<typename string_type::value_type>& is, basic_json<CharT, Alloc>& o)
- {
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_reader<typename string_type::value_type> reader(is, handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- o = handler.get_result();
- return is;
- }
-};
-
-template <class JsonT>
-void swap(typename JsonT::member_type& a, typename JsonT::member_type& b)
-{
- a.swap(b);
-}
-
-template<typename CharT, typename Alloc>
-bool basic_json<CharT, Alloc>::operator!=(const basic_json<CharT, Alloc>& rhs) const
-{
- return !(*this == rhs);
-}
-
-template<typename CharT, typename Alloc>
-bool basic_json<CharT, Alloc>::operator==(const basic_json<CharT, Alloc>& rhs) const
-{
- return var_ == rhs.var_;
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_2d_array(size_t m, size_t n)
-{
- basic_json<CharT, Alloc> a = basic_json<CharT, Alloc>::array();
- a.resize(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_array(n);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-template<typename T>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_2d_array(size_t m, size_t n, T val)
-{
- basic_json<CharT, Alloc> v;
- v = val;
- basic_json<CharT, Alloc> a = make_array(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_array(n, v);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_3d_array(size_t m, size_t n, size_t k)
-{
- basic_json<CharT, Alloc> a = basic_json<CharT, Alloc>::array();
- a.resize(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_2d_array(n, k);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-template<typename T>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::make_3d_array(size_t m, size_t n, size_t k, T val)
-{
- basic_json<CharT, Alloc> v;
- v = val;
- basic_json<CharT, Alloc> a = make_array(m);
- for (size_t i = 0; i < a.size(); ++i)
- {
- a[i] = basic_json<CharT, Alloc>::make_2d_array(n, k, v);
- }
- return a;
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_stream(std::basic_istream<char_type>& is)
-{
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_reader<char_type> reader(is, handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_stream(std::basic_istream<char_type>& is,
- basic_parse_error_handler<char_type>& err_handler)
-{
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- basic_json_reader<char_type> reader(is, handler, err_handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_file(const std::string& filename)
-{
- FILE* fp;
-
-#if defined(JSONCONS_HAS_FOPEN_S)
- errno_t err = fopen_s(&fp, filename.c_str(), "rb");
- if (err != 0)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#else
- fp = std::fopen(filename.c_str(), "rb");
- if (fp == nullptr)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#endif
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- try
- {
- // obtain file size:
- std::fseek (fp , 0 , SEEK_END);
- long size = std::ftell (fp);
- std::rewind(fp);
-
- if (size > 0)
- {
- std::vector<char_type> buffer(size);
-
- // copy the file into the buffer:
- size_t result = std::fread (buffer.data(),1,size,fp);
- if (result != static_cast<unsigned long long>(size))
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Error reading file %s", filename);
- }
-
- basic_json_parser<char_type> parser(handler);
- parser.begin_parse();
- parser.parse(buffer.data(),0,buffer.size());
- parser.end_parse();
- parser.check_done(buffer.data(),parser.index(),buffer.size());
- }
-
- std::fclose (fp);
- }
- catch (...)
- {
- std::fclose (fp);
- throw;
- }
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json file");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-basic_json<CharT, Alloc> basic_json<CharT, Alloc>::parse_file(const std::string& filename,
- basic_parse_error_handler<char_type>& err_handler)
-{
- FILE* fp;
-
-#if !defined(JSONCONS_HAS_FOPEN_S)
- fp = std::fopen(filename.c_str(), "rb");
- if (fp == nullptr)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#else
- errno_t err = fopen_s(&fp, filename.c_str(), "rb");
- if (err != 0)
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Cannot open file %s", filename);
- }
-#endif
-
- basic_json_deserializer<basic_json<CharT, Alloc>> handler;
- try
- {
- // obtain file size:
- std::fseek (fp , 0 , SEEK_END);
- long size = std::ftell (fp);
- std::rewind(fp);
-
- if (size > 0)
- {
- std::vector<char_type> buffer(size);
-
- // copy the file into the buffer:
- size_t result = std::fread (buffer.data(),1,size,fp);
- if (result != static_cast<unsigned long long>(size))
- {
- JSONCONS_THROW_EXCEPTION_1(std::runtime_error,"Error reading file %s", filename);
- }
-
- basic_json_parser<char_type> parser(handler,err_handler);
- parser.begin_parse();
- parser.parse(buffer.data(),0,buffer.size());
- parser.end_parse();
- parser.check_done(buffer.data(),parser.index(),buffer.size());
- }
-
- std::fclose (fp);
- }
- catch (...)
- {
- std::fclose (fp);
- throw;
- }
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json file");
- }
- return handler.get_result();
-}
-
-template<typename CharT, typename Alloc>
-typename basic_json<CharT, Alloc>::any& basic_json<CharT, Alloc>::any_value()
-{
- switch (var_.type_)
- {
- case value_types::any_t:
- {
- return *var_.value_.any_val_;
- }
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an any value");
- }
-}
-
-template<typename CharT, typename Alloc>
-const typename basic_json<CharT, Alloc>::any& basic_json<CharT, Alloc>::any_value() const
-{
- switch (var_.type_)
- {
- case value_types::any_t:
- {
- return *var_.value_.any_val_;
- }
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Not an any value");
- }
-}
-
-template <typename JsonT>
-std::basic_istream<typename JsonT::char_type>& operator>>(std::basic_istream<typename JsonT::char_type>& is, JsonT& o)
-{
- basic_json_deserializer<JsonT> handler;
- basic_json_reader<typename JsonT::char_type> reader(is, handler);
- reader.read_next();
- reader.check_done();
- if (!handler.is_valid())
- {
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Failed to parse json stream");
- }
- o = handler.get_result();
- return is;
-}
-
-template<typename JsonT>
-class json_printable
-{
-public:
- typedef typename JsonT::char_type char_type;
-
- json_printable(const JsonT& o,
- bool is_pretty_print)
- : o_(&o), is_pretty_print_(is_pretty_print)
- {
- }
-
- json_printable(const JsonT& o,
- bool is_pretty_print,
- const basic_output_format<char_type>& format)
- : o_(&o), is_pretty_print_(is_pretty_print), format_(format)
- {
- ;
- }
-
- void to_stream(std::basic_ostream<char_type>& os) const
- {
- o_->to_stream(os, format_, is_pretty_print_);
- }
-
- friend std::basic_ostream<char_type>& operator<<(std::basic_ostream<char_type>& os, const json_printable<JsonT>& o)
- {
- o.to_stream(os);
- return os;
- }
-
- const JsonT *o_;
- bool is_pretty_print_;
- basic_output_format<char_type> format_;
-private:
- json_printable();
-};
-
-template<typename JsonT>
-json_printable<JsonT> print(const JsonT& val)
-{
- return json_printable<JsonT>(val,false);
-}
-
-template<class JsonT>
-json_printable<JsonT> print(const JsonT& val,
- const basic_output_format<typename JsonT::char_type>& format)
-{
- return json_printable<JsonT>(val, false, format);
-}
-
-template<class JsonT>
-json_printable<JsonT> pretty_print(const JsonT& val)
-{
- return json_printable<JsonT>(val,true);
-}
-
-template<typename JsonT>
-json_printable<JsonT> pretty_print(const JsonT& val,
- const basic_output_format<typename JsonT::char_type>& format)
-{
- return json_printable<JsonT>(val, true, format);
-}
-
-typedef basic_json<char,std::allocator<char>> json;
-typedef basic_json<wchar_t,std::allocator<wchar_t>> wjson;
-
-typedef basic_json_deserializer<json> json_deserializer;
-typedef basic_json_deserializer<wjson> wjson_deserializer;
-
-}
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
-#endif