20#include <initializer_list>
34class object_node_handle;
55inline constexpr std::size_t value_inline_string_capacity = 14U;
58inline constexpr unsigned char value_string_out_of_line = 0xffU;
65 unsigned char string_length;
70struct value_short_string
73 unsigned char string_length;
74 char text[value_inline_string_capacity];
80union value_representation
83 value_short_string short_string;
85 constexpr value_representation() :
90static_assert(
sizeof(value_representation) == 16U,
"a value is 16 bytes");
110 public std::logic_error
113 explicit kind_error(
const std::string& description);
158 typedef std::size_t size_type;
159 typedef std::ptrdiff_t difference_type;
162 template <
typename T,
typename TArrayView>
166 using iterator_category = std::random_access_iterator_tag;
167 using value_type = T;
168 using difference_type = std::ptrdiff_t;
170 using reference = T&;
181 template <
typename U,
typename UArrayView>
183 typename std::enable_if<std::is_convertible<U*, T*>::value>::type* = 0
185 _owner(source._owner),
186 _index(source._index)
215 template <
typename U,
typename UArrayView>
219 return _owner == other._owner && _index == other._index;
222 template <
typename U,
typename UArrayView>
226 return !operator==(other);
232 return _owner->operator[](_index);
236 T* operator->()
const
238 return &_owner->operator[](_index);
272 return difference_type(_index) - difference_type(other._index);
278 return _index < rhs._index;
284 return _index <= rhs._index;
290 return _index > rhs._index;
296 return _index >= rhs._index;
300 T& operator[](size_type n)
const
302 return _owner->operator[](_index + n);
305 template <
typename U,
typename UArrayView>
324 typedef detail::basic_view<array_iterator, const_array_iterator>
array_view;
325 typedef detail::basic_view<const_array_iterator> const_array_view;
326 typedef detail::basic_owning_view<value, array_iterator, const_array_iterator> owning_array_view;
344 template <
typename TValue>
377 template <
typename UValue,
378 typename = std::enable_if_t< !std::is_same_v<UValue, TValue>
379 && std::is_convertible_v<UValue&, TValue&>
384 second(source.second)
392 template <
typename TPair,
typename = std::enable_if_t<std::is_same_v<TPair,
object_value_type>>>
394 explicit operator TPair()
const
396 return TPair(first, second);
414 template <
typename TValue,
typename TMember>
424 using difference_type = std::ptrdiff_t;
446 template <
typename UValue,
448 typename = std::enable_if_t< !std::is_same_v<UMember, TMember>
449 && std::is_convertible_v<UMember*, TMember*>
453 _member(source._member)
462 basic_object_iterator operator++(
int)
noexcept
464 basic_object_iterator clone(*
this);
469 basic_object_iterator& operator--() noexcept
475 basic_object_iterator operator--(
int)
noexcept
477 basic_object_iterator clone(*
this);
482 basic_object_iterator& operator+=(difference_type n)
noexcept
488 basic_object_iterator& operator-=(difference_type n)
noexcept
495 basic_object_iterator operator+(difference_type n)
const noexcept
497 return basic_object_iterator(_member + n);
501 friend basic_object_iterator operator+(difference_type n,
const basic_object_iterator& iter)
noexcept
507 basic_object_iterator operator-(difference_type n)
const noexcept
509 return basic_object_iterator(_member - n);
512 template <
typename UValue,
typename UMember>
514 difference_type operator-(
const basic_object_iterator<UValue, UMember>& other)
const noexcept
516 return _member - other._member;
519 template <
typename UValue,
typename UMember>
521 bool operator==(
const basic_object_iterator<UValue, UMember>& other)
const noexcept
523 return _member == other._member;
526 template <
typename UValue,
typename UMember>
528 auto operator<=>(
const basic_object_iterator<UValue, UMember>& other)
const noexcept
530 return _member <=> other._member;
534 reference operator*() const noexcept
536 return reference(_member->first, _member->second);
540 pointer operator->() const noexcept
542 return pointer{ **
this };
546 reference operator[](difference_type n)
const noexcept
552 template <
typename UValue,
typename UMember>
553 friend struct basic_object_iterator;
557 explicit basic_object_iterator(TMember* member) noexcept :
574 typedef detail::basic_view<object_iterator, const_object_iterator>
object_view;
575 typedef detail::basic_view<const_object_iterator> const_object_view;
576 typedef detail::basic_owning_view<value, object_iterator, const_object_iterator> owning_object_view;
641 #define JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR(type_) \
644 #undef JSONV_VALUE_INTEGER_ALTERNATIVE_CTOR_PROTO_GENERATOR
671 std::string_view as_string() const;
675 bool is_string() const;
682 std::string_view as_string_view() const &;
692 std::wstring as_wstring() const;
699 int64_t as_integer() const;
703 bool is_integer() const;
711 double as_decimal() const;
715 bool is_decimal() const;
722 bool as_boolean() const;
726 bool is_boolean() const;
730 bool is_array() const;
734 bool is_object() const;
738 bool is_null() const;
747 return _repr.words.kind;
868 bool operator< (
const value& other)
const;
870 bool operator> (
const value& other)
const;
872 bool operator<=(
const value& other)
const;
874 bool operator>=(
const value& other)
const;
915 owning_array_view as_array() &&;
926 const
value& operator[](size_type idx) const;
967 template <
typename TForwardIterator>
972 for (difference_type offset = orig_offset ; first != last; ++first, ++offset)
973 insert(begin_array() + offset, *first);
974 return begin_array() + orig_offset;
985 template <
typename TForwardIterator>
986 void assign(TForwardIterator first, TForwardIterator last)
988 resize(std::distance(first, last),
value());
989 auto iter = begin_array();
990 while (first != last)
1001 void assign(std::initializer_list<value> items);
1059 owning_object_view as_object() &&;
1096 size_type count(const
std::
string& key) const;
1098 size_type count(const
std::wstring& key) const;
1156 template <typename TForwardIterator>
1157 void insert(TForwardIterator first, TForwardIterator last)
1163 for ( ; first != last; ++first)
1164 hint =
insert(hint, *first) + 1;
1202 void insert(std::initializer_list<std::pair<std::string, value>> items);
1203 void insert(std::initializer_list<std::pair<std::wstring, value>> items);
1225 std::pair<object_iterator, bool>
emplace(
const std::wstring& key,
value val);
1276 size_type
erase(
const std::string& key);
1277 size_type
erase(
const std::wstring& key);
1338 size_type size() const;
1376 friend struct detail::value_access;
1379 detail::value_representation _repr;
1409template <typename TForwardIterator>
1410value array(TForwardIterator first, TForwardIterator last)
1425template <
typename TForwardIterator>
1461 bool empty() const noexcept {
return !_has_value; }
1465 explicit operator bool() const noexcept {
return _has_value; }
1478 enum class purposeful_construction
1481 explicit object_node_handle(purposeful_construction, key_type, mapped_type)
noexcept;
1487 mutable key_type _key;
1488 mutable mapped_type _value;
1508 std::size_t operator()(
const jsonv::value& val)
const noexcept;
1513template <
typename TValue,
template <
typename>
class TQual,
template <
typename>
class UQual>
1514struct basic_common_reference<jsonv::value::basic_object_reference<TValue>,
1524template <
typename TValue,
template <
typename>
class TQual,
template <
typename>
class UQual>
1525struct basic_common_reference<jsonv::value::object_value_type,
Copyright (c) 2014-2020 by Travis Gockel.
Thrown from various value methods when attempting to perform an operation which is not valid for the ...
A node handle used when a value is kind::object to access elements of the object in potentially destr...
object_node_handle & operator=(object_node_handle &&src) noexcept
Release the element this handle owns, if any, and take over the one owned by src, if any.
key_type & key() const
Returns a non-const reference to the key_type member of the element.
mapped_type & mapped() const
Returns a non-const reference to the mapped_type member of the element.
std::string key_type
The key type of the object.
object_node_handle(object_node_handle &&src) noexcept
Take over the element owned by src, if any. src is left empty.
Represents an exact path in some JSON structure.
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
void assign(TForwardIterator first, TForwardIterator last)
Assign the contents of range [first, last) to this array.
const value & at_path(std::string_view p) const
Get the value specified by the path p.
value(const std::string_view &value)
Create a kind::string with the given value.
void insert(std::initializer_list< std::pair< std::wstring, value > > items)
Insert items into this object.
value(std::nullptr_t)=delete
The nullptr overload will fail to compile – use jsonv::null if you want a kind::null.
std::pair< object_iterator, bool > emplace(const std::wstring &key, value val)
Construct an element from key and val and insert it into this object.
array_iterator erase(const_array_iterator first, const_array_iterator last)
Erase the range [first, last) from this array.
value(float value)
Create a kind::decimal with the given value.
value & at_path(const path &p)
Get the value specified by the path p.
const value & at_path(size_type p) const
Get the value specified by the path p.
value & path(const path &p)
Get or create the value specified by the path p.
friend std::ostream & operator<<(std::ostream &stream, const value &val)
Output this value to a stream, through an ostream_encoder.
const_object_iterator end_object() const
Get an iterator to the one past the end of this object.
std::pair< object_iterator, bool > try_emplace(const std::wstring &key, value val)
Insert val with the given key into this object, but only if no element with an equivalent key is alre...
value & at_path(std::string_view p)
Get the value specified by the path p.
void assign(size_type count, const value &val)
Assign count elements to this array with val.
object_iterator erase(const_object_iterator position)
Erase the item at the given position.
value & at_path(size_type p)
Get the value specified by the path p.
const value & at_path(const path &p) const
Get the value specified by the path p.
size_type count_path(const path &p) const
Similar to count, but walks the given path p to determine its presence.
bool operator!=(const value &other) const
Compares two JSON values for inequality.
detail::basic_view< object_iterator, const_object_iterator > object_view
If kind is kind::object, an object_view allows you to access a value as an associative container.
basic_object_reference< const value > const_object_reference
array_view as_array() &
View this instance as an array.
object_iterator end_object()
Get an iterator to the one past the end of this object.
const value & operator[](int idx) const
Get the value in this array at the given idx.
int compare(const value &other) const
Used to build a strict-ordering of JSON values.
object_node_handle extract(const_object_iterator position)
Move the key and value of the member at position into a node handle, erase the member,...
size_type count_path(std::string_view p) const
Similar to count, but walks the given path p to determine its presence.
void push_back(const value &item)
Push item to the back of this array.
const_object_iterator begin_object() const
Get an iterator to the first key-value pair in this object.
detail::basic_view< array_iterator, const_array_iterator > array_view
If kind is kind::array, an array_view allows you to access a value as a sequence container.
object_node_handle extract(const std::string &key)
If the container has an element with the given key, moves its key and value into a node handle,...
size_type count_path(size_type p) const
Similar to count, but walks the given path p to determine its presence.
value(const wchar_t *value)
Create a kind::string with the given value.
constexpr value()=default
Default-construct this to null.
const_array_iterator begin_array() const
Get an iterator to the beginning of this array.
object_insert_return_type insert(object_node_handle &&handle)
Insert the contents of handle.
std::pair< object_iterator, bool > try_emplace(const std::string &key, value val)
Insert val with the given key into this object, but only if no element with an equivalent key is alre...
object_iterator insert(const_object_iterator hint, object_node_handle &&handle)
If handle is an empty node handle, does nothing and returns end_object.
array_iterator erase(const_array_iterator position)
Erase the item at this array's position.
std::pair< object_iterator, bool > insert_or_assign(const std::wstring &key, value val)
Insert val with the given key into this object if no element with an equivalent key is present; other...
basic_object_reference< value > object_reference
bool operator==(const value &other) const
Compares two JSON values for equality.
array_iterator insert(const_array_iterator position, TForwardIterator first, TForwardIterator last)
Insert the range defined by [first, last) at position in this array.
friend JSONV_PUBLIC value object()
Create an empty object.
void push_back(value &&item)
Push item to the back of this array.
basic_object_iterator< value, std::pair< std::string, value > > object_iterator
The object_iterator is applicable when kind is kind::object.
void resize(size_type count, const value &val=value())
Resize the length of this array to count items.
value & at(size_type idx)
Get the value in this array at the given idx.
std::pair< object_iterator, bool > emplace(std::string key, value val)
Construct an element from key and val and insert it into this object.
value(const std::wstring &value)
Create a kind::string with the given value.
const value & at(size_type idx) const
Get the value in this array at the given idx.
const_array_iterator end_array() const
Get an iterator to the end of this array.
value(bool value)
Create a kind::boolean with the given value.
basic_array_iterator< value, value > array_iterator
The array_iterator is applicable when kind is kind::array.
~value() noexcept
Destruction will never throw.
value(const value &source)
Copy the contents of source into a new instance.
std::pair< object_iterator, bool > insert_or_assign(const std::string &key, value val)
Insert val with the given key into this object if no element with an equivalent key is present; other...
std::pair< const std::string, value > object_value_type
The type of value stored when kind is kind::object, as an owning pair.
size_type erase(const std::wstring &key)
Erase the item with the given key.
const_object_iterator position
The position of the inserted member or the member with the duplicate key.
value(const std::string &value)
Create a kind::string with the given value.
void swap(value &other) noexcept
Swap the value this instance represents with other.
object_iterator begin_object()
Get an iterator to the first key-value pair in this object.
value & operator[](int idx)
Get the value in this array at the given idx.
void insert(std::initializer_list< std::pair< std::string, value > > items)
Insert items into this object.
bool inserted
Did the insert operation perform an insert? A value of false indicates there was a key already presen...
object_view as_object() &
View this instance as an object.
bool empty() const noexcept
Is the underlying structure empty?
friend std::string to_string(const value &)
Get a string representation of the given value.
value(const char *value)
Create a kind::string with the given value.
void pop_back()
Pop an item off the back of this array.
object_iterator erase(const_object_iterator first, const_object_iterator last)
Erase the range defined by [first, last).
array_iterator insert(const_array_iterator position, value item)
Insert an item into position on this array.
const_object_view as_object() const &
View this instance as an object.
size_type erase(const std::string &key)
Erase the item with the given key.
value & path(size_type p)
Get or create the value specified by the path p.
object_node_handle extract(const std::wstring &key)
If the container has an element with the given key, moves its key and value into a node handle,...
array_iterator begin_array()
Get an iterator to the beginning of this array.
array_iterator end_array()
Get an iterator to the end of this array.
value(double value)
Create a kind::decimal with the given value.
void assign(std::initializer_list< value > items)
Assign the given items to this array.
value & path(std::string_view p)
Get or create the value specified by the path p.
value(int64_t value)
Create a kind::integer with the given value.
void reserve(size_type count)
Reserve at least count elements in the array.
const_array_view as_array() const &
View this instance as an array.
Type returned from insert operations when this has kind::object.
Copyright (c) 2014-2020 by Travis Gockel.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
#define JSONV_INTEGER_ALTERNATES_LIST(item)
An item list of types to also consider as an integer.
#define JSONV_PUBLIC
This function or class is part of the public API for JSON Voorhees.
@ insert
Insert the correct key/value pair as part of serialization.
kind
Describes the kind of data a value holds.
JSONV_PUBLIC std::string to_string(const ast_node_type &type)
Get what operator<< writes for type as a std::string.
JSONV_PUBLIC value object()
Create an empty object.
JSONV_PUBLIC const value null
An instance with kind::null.
JSONV_PUBLIC value array()
Create an empty array value.
Copyright (c) 2019-2020 by Travis Gockel.
The base type for iterating over array values.
What operator-> returns: it holds the reference, so iter->first and iter->second work.
const reference * operator->() const noexcept
The member the iterator was at, for the built-in -> to reach into.
reference ref
The member the iterator was at.
The base iterator type for iterating over object types.
std::random_access_iterator_tag iterator_category
What this gives the functions which dispatch on the category.
std::random_access_iterator_tag iterator_concept
What this models in C++20 terms: a random-access iterator, whose reference may be a proxy.
basic_object_iterator(const basic_object_iterator< UValue, UMember > &source) noexcept
This allows conversion from an object_iterator to a const_object_iterator.
What dereferencing an object_iterator (TValue of value) or a const_object_iterator (TValue of const v...
basic_object_reference(const basic_object_reference< UValue > &source) noexcept
This allows conversion from an object_reference to a const_object_reference.
const std::string first_type
The type of first, as in std::pair, which this stands in for.
TValue second_type
The type of second, as in std::pair.
const std::string & first
The key of the member.
TValue & second
The value of the member.
basic_object_reference(const std::string &key, TValue &val) noexcept
Refer to key and val.
basic_object_reference(std::conditional_t< std::is_const_v< TValue >, const object_value_type &, object_value_type & > pair) noexcept
Refer to the key and value of pair.