mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 21:53:58 +00:00
1429 lines
31 KiB
C++
1429 lines
31 KiB
C++
//
|
|
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// Official repository: https://github.com/vinniefalco/json
|
|
//
|
|
|
|
#ifndef BOOST_JSON_VALUE_HPP
|
|
#define BOOST_JSON_VALUE_HPP
|
|
|
|
#include <boost/json/detail/config.hpp>
|
|
#include <boost/json/array.hpp>
|
|
#include <boost/json/error.hpp>
|
|
#include <boost/json/kind.hpp>
|
|
#include <boost/json/number.hpp>
|
|
#include <boost/json/object.hpp>
|
|
#include <boost/json/storage_ptr.hpp>
|
|
#include <boost/json/string.hpp>
|
|
#include <boost/json/detail/is_specialized.hpp>
|
|
#include <boost/json/detail/value.hpp>
|
|
#include <boost/json/detail/assert.hpp>
|
|
#include <boost/utility/string_view.hpp>
|
|
#include <boost/pilfer.hpp>
|
|
#include <cstdlib>
|
|
#include <initializer_list>
|
|
#include <iosfwd>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
namespace boost {
|
|
namespace json {
|
|
|
|
class value;
|
|
|
|
/** Customization point for assigning to and from class types.
|
|
*/
|
|
template<class T>
|
|
struct value_exchange final
|
|
#ifndef GENERATING_DOCUMENTATION
|
|
: detail::primary_template
|
|
#endif
|
|
{
|
|
static
|
|
void
|
|
to_json(T const& t, value& v)
|
|
{
|
|
detail::call_to_json(t, v);
|
|
}
|
|
|
|
static
|
|
void
|
|
from_json(T& t, value const& v)
|
|
{
|
|
detail::call_from_json(t, v);
|
|
}
|
|
};
|
|
|
|
/** Trait to determine if a type can be assigned to a json value.
|
|
*/
|
|
template<class T>
|
|
using has_from_json =
|
|
#ifdef GENERATING_DOCUMENTATION
|
|
__see_below__;
|
|
#else
|
|
std::integral_constant<bool,
|
|
detail::is_specialized<value_exchange<
|
|
detail::remove_cr<T>>>::value ||
|
|
detail::has_adl_from_json<
|
|
detail::remove_cr<T>>::value ||
|
|
detail::has_mf_from_json<
|
|
detail::remove_cr<T>>::value>;
|
|
#endif
|
|
|
|
/** Returns `true` if a JSON value can be constructed from `T`
|
|
*/
|
|
template<class T>
|
|
using has_to_json =
|
|
#ifdef GENERATING_DOCUMENTATION
|
|
__see_below__;
|
|
#else
|
|
std::integral_constant<bool,
|
|
detail::is_specialized<value_exchange<
|
|
detail::remove_cr<T>>>::value ||
|
|
detail::has_adl_to_json<
|
|
detail::remove_cr<T>>::value ||
|
|
detail::has_mf_to_json<
|
|
detail::remove_cr<T>>::value>;
|
|
#endif
|
|
|
|
//----------------------------------------------------------
|
|
|
|
/** The type used to represent any JSON value
|
|
|
|
@par Thread Safety:
|
|
|
|
Distinct instances may be accessed concurrently.
|
|
Non-const member functions of a shared instance
|
|
may not be called concurrently with any other
|
|
member functions of that instance.
|
|
*/
|
|
class value
|
|
{
|
|
struct undo;
|
|
struct init_iter;
|
|
friend class value_test;
|
|
|
|
#ifndef GENERATING_DOCUMENTATION
|
|
struct scalar
|
|
{
|
|
storage_ptr sp;
|
|
union
|
|
{
|
|
number num;
|
|
bool b;
|
|
};
|
|
|
|
~scalar()
|
|
{
|
|
}
|
|
};
|
|
|
|
// XSL scripts have trouble with private anon unions
|
|
union
|
|
{
|
|
object obj_;
|
|
array arr_;
|
|
string str_;
|
|
scalar sca_;
|
|
};
|
|
#endif
|
|
|
|
json::kind kind_;
|
|
|
|
public:
|
|
/// Destroy a value and all of its contents
|
|
BOOST_JSON_DECL
|
|
~value();
|
|
|
|
/** Construct a null value
|
|
|
|
The container and all of its contents will use the
|
|
default storage.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value() noexcept;
|
|
|
|
/** Construct a null value
|
|
|
|
The container and all of its contents will use the
|
|
specified storage object.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
|
|
@param sp A pointer to the @ref storage to use. The
|
|
container will acquire shared ownership of the pointer.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
explicit
|
|
value(storage_ptr sp) noexcept;
|
|
|
|
/** Construct a value of the specified kind
|
|
|
|
The container and all of its contents will use the
|
|
specified storage object.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
|
|
@param k The kind of JSON value.
|
|
|
|
@param sp A pointer to the @ref storage to use. The
|
|
container will acquire shared ownership of the pointer.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(
|
|
json::kind k,
|
|
storage_ptr sp = default_storage()) noexcept;
|
|
|
|
BOOST_JSON_DECL
|
|
value(
|
|
kind_array_t,
|
|
storage_ptr sp = default_storage()) noexcept;
|
|
|
|
BOOST_JSON_DECL
|
|
value(
|
|
kind_null_t,
|
|
storage_ptr sp = default_storage()) noexcept;
|
|
|
|
/** Copy constructor
|
|
|
|
The container and all of its contents will use the
|
|
default storage.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the size of `other`.
|
|
|
|
@param other The value to copy.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(value const& other);
|
|
|
|
/** Copy constructor
|
|
|
|
The container and all of its contents will use the
|
|
specified storage object.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the size of `other`.
|
|
|
|
@param other The value to copy.
|
|
|
|
@param sp A pointer to the @ref storage to use. The
|
|
container will acquire shared ownership of the pointer.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(
|
|
value const& other,
|
|
storage_ptr sp);
|
|
|
|
/** Pilfer constructor
|
|
|
|
Constructs the container with the contents of `other`
|
|
using pilfer semantics.
|
|
Ownership of the @ref storage is transferred.
|
|
|
|
@note
|
|
|
|
After construction, the moved-from object may only be
|
|
destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
|
|
@param other The container to pilfer
|
|
|
|
@see
|
|
|
|
Pilfering constructors are described in
|
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0308r0.html">Valueless Variants Considered Harmful</a>, by Peter Dimov.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(pilfered<value> other) noexcept;
|
|
|
|
/** Move constructor
|
|
|
|
Constructs the container with the contents of `other`
|
|
using move semantics. Ownership of the underlying
|
|
memory is transferred.
|
|
The container acquires shared ownership of the
|
|
@ref storage used by `other`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
|
|
@param other The container to move
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(value&& other) noexcept;
|
|
|
|
/** Move constructor
|
|
|
|
Using `*sp` as the @ref storage for the new container,
|
|
moves all the elements from `other`.
|
|
|
|
@li If `*other.get_storage() == *sp`, ownership of the
|
|
underlying memory is transferred in constant time, with
|
|
no possibility of exceptions.
|
|
|
|
@li If `*other.get_storage() != *sp`, a copy is performed.
|
|
In this case, the moved-from container is not changed.
|
|
|
|
The container and all of its contents will use the
|
|
specified storage object.
|
|
|
|
@par Complexity
|
|
|
|
Constant or linear in the size of `other`.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
Calls to @ref storage::allocate may throw.
|
|
|
|
@param other The container to move
|
|
|
|
@param sp A pointer to the @ref storage to use. The
|
|
container array will acquire shared ownership of the pointer.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(
|
|
value&& other,
|
|
storage_ptr sp);
|
|
|
|
/** Move assignment operator
|
|
|
|
Replaces the contents with those of `other` using move
|
|
semantics (the data in `other` is moved into this container).
|
|
|
|
@li If `*other.get_storage() == get_storage()`,
|
|
ownership of the underlying memory is transferred in
|
|
constant time, with no possibility of exceptions.
|
|
|
|
@li If `*other.get_storage() != *sp`, a copy is performed.
|
|
In this case the moved-from container is not modified,
|
|
and exceptions may be thrown.
|
|
|
|
@par Complexity
|
|
|
|
Constant or linear in the size of `*this` plus `other`.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
Calls to @ref storage::allocate may throw.
|
|
|
|
@param other The container to assign from
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value& operator=(value&& other);
|
|
|
|
/** Copy assignment operator
|
|
|
|
Replaces the contents with a copy of `other`.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the size of `*this` plus `other`.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
Calls to @ref storage::allocate may throw.
|
|
|
|
@param other The container to copy
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value& operator=(value const& other);
|
|
|
|
//------------------------------------------------------
|
|
//
|
|
// Conversion
|
|
//
|
|
//------------------------------------------------------
|
|
|
|
/** Construct an object
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(object obj) noexcept;
|
|
|
|
/** Construct an object
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(object obj, storage_ptr sp);
|
|
|
|
/** Construct an array
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(array arr) noexcept;
|
|
|
|
/** Construct an array
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(array arr, storage_ptr sp);
|
|
|
|
/** Construct a string
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(string str) noexcept;
|
|
|
|
/** Construct a string
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(string str, storage_ptr sp);
|
|
|
|
/** Construct a number
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(number num,
|
|
storage_ptr sp = default_storage());
|
|
|
|
/** Construct a bool
|
|
*/
|
|
#ifdef GENERATING_DOCUMENTATION
|
|
value(bool b,
|
|
storage_ptr = default_storage()) noexcept;
|
|
#else
|
|
template<class Bool
|
|
,class = typename std::enable_if<
|
|
std::is_same<Bool, bool>::value>::type
|
|
>
|
|
value(Bool b,
|
|
storage_ptr sp =
|
|
default_storage()) noexcept;
|
|
#endif
|
|
|
|
/** Construct an object or array
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value(
|
|
std::initializer_list<value> init,
|
|
storage_ptr sp = default_storage());
|
|
|
|
/** Assign to this value
|
|
*/
|
|
template<class T
|
|
#ifndef GENERATING_DOCUMENTATION
|
|
,class = typename std::enable_if<
|
|
std::is_constructible<value, T>::value>::type
|
|
#endif
|
|
>
|
|
value&
|
|
operator=(T&& t)
|
|
{
|
|
value tmp(
|
|
std::forward<T>(t),
|
|
get_storage());
|
|
tmp.swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
//------------------------------------------------------
|
|
//
|
|
// Modifiers
|
|
//
|
|
//------------------------------------------------------
|
|
|
|
/** Reset the json to the specified type.
|
|
|
|
This changes the value to hold a newly
|
|
constructed value of the specified type.
|
|
The previous contents are destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the existing size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
|
|
@param k The kind to set.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
value&
|
|
reset(json::kind k = json::kind::null) noexcept;
|
|
|
|
/** Set the value to an empty object, and return it.
|
|
|
|
This calls `reset(json::kind::object)` and returns
|
|
@ref as_object().
|
|
The previous contents are destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the existing size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
object&
|
|
emplace_object() noexcept
|
|
{
|
|
reset(json::kind::object);
|
|
return obj_;
|
|
}
|
|
|
|
/** Set the value to an empty array, and return it.
|
|
|
|
This calls `reset(json::kind::array)` and returns
|
|
@ref as_array().
|
|
The previous contents are destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the existing size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
array&
|
|
emplace_array() noexcept
|
|
{
|
|
reset(json::kind::array);
|
|
return arr_;
|
|
}
|
|
|
|
/** Set the value to an empty string, and return it.
|
|
|
|
This calls `reset(json::kind::string)` and returns
|
|
@ref as_string().
|
|
The previous contents are destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the existing size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
string&
|
|
emplace_string() noexcept
|
|
{
|
|
reset(json::kind::string);
|
|
return str_;
|
|
}
|
|
|
|
/** Set the value to the number 0, and return it.
|
|
|
|
This calls `reset(json::kind::number)` and returns
|
|
@ref as_number().
|
|
The previous contents are destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the existing size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
number&
|
|
emplace_number() noexcept
|
|
{
|
|
reset(json::kind::number);
|
|
return sca_.num;
|
|
}
|
|
|
|
/** Set the value to boolean false, and return it.
|
|
|
|
This calls `reset(json::kind::boolean)` and returns
|
|
@ref as_bool().
|
|
The previous contents are destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the existing size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
bool&
|
|
emplace_bool() noexcept
|
|
{
|
|
reset(json::kind::boolean);
|
|
return sca_.b;
|
|
}
|
|
|
|
/** Set the value to null.
|
|
|
|
This calls `reset(json::kind::null)`.
|
|
The previous contents are destroyed.
|
|
|
|
@par Complexity
|
|
|
|
Linear in the existing size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
void
|
|
emplace_null() noexcept
|
|
{
|
|
reset(json::kind::null);
|
|
}
|
|
|
|
/** Swap the contents
|
|
|
|
Exchanges the contents of this container with another
|
|
container.
|
|
All iterators and references remain valid.
|
|
|
|
@par Precondition
|
|
|
|
`*get_storage() == *other.get_storage()`
|
|
|
|
@par Complexity
|
|
|
|
Constant or linear in the size of `*this` plus `other`.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
Calls to @ref storage::allocate may throw.
|
|
|
|
@param other The container to swap with
|
|
*/
|
|
BOOST_JSON_DECL
|
|
void
|
|
swap(value& other);
|
|
|
|
//------------------------------------------------------
|
|
//
|
|
// Exchange
|
|
//
|
|
//------------------------------------------------------
|
|
|
|
/// Construct from another type using the specified storage
|
|
template<
|
|
class T
|
|
#ifndef GENERATING_DOCUMENTATION
|
|
,class = typename std::enable_if<
|
|
has_to_json<T>::value>::type
|
|
#endif
|
|
>
|
|
value(
|
|
T const& t,
|
|
storage_ptr sp = default_storage())
|
|
: value(std::move(sp))
|
|
{
|
|
value_exchange<
|
|
detail::remove_cr<T>
|
|
>::to_json(t, *this);
|
|
}
|
|
|
|
/// Assign a value from another type
|
|
template<
|
|
class T
|
|
#ifndef GENERATING_DOCUMENTATION
|
|
,class = typename std::enable_if<
|
|
has_to_json<T>::value>::type
|
|
#endif
|
|
>
|
|
value&
|
|
operator=(T const& t)
|
|
{
|
|
value_exchange<
|
|
detail::remove_cr<T>
|
|
>::to_json(t, *this);
|
|
return *this;
|
|
}
|
|
|
|
/** Try to assign a value to another type
|
|
|
|
This function attempts to assign the contents of
|
|
`*this` to the variable `t`.
|
|
@par Complexity
|
|
|
|
Linear in the size of `*this`.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throws system error Thrown upon failure
|
|
*/
|
|
template<class T>
|
|
void
|
|
store(T& t) const
|
|
{
|
|
// If this assert goes off, it means that there are no known
|
|
// ways to convert a JSON value into a user defined type `T`.
|
|
// There are three ways to fix this:
|
|
//
|
|
// 1. Add the member function `T::from_json(value const&)`,
|
|
//
|
|
// 2. Add the free function `from_json(T&, value const&)`
|
|
// in the same namespace as T, or
|
|
//
|
|
// 3. Specialize `json::value_exchange` for `T`, and provide
|
|
// the static member `from_json(T&, value const&)`.
|
|
|
|
static_assert(
|
|
has_from_json<T>::value,
|
|
"Destination type is unknown");
|
|
value_exchange<
|
|
detail::remove_cr<T>
|
|
>::from_json(t, *this);
|
|
}
|
|
|
|
//------------------------------------------------------
|
|
|
|
/** Returns `true` if this is an array containing only a key and value
|
|
|
|
This function returns `true` if all the following
|
|
conditions are met:
|
|
|
|
@li @ref kind() returns `kind::array`
|
|
@li `this->as_array().size() == 2`
|
|
@li `this->as_array()[0].is_string() == true`
|
|
|
|
Otherwise, the function returns `false`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
bool
|
|
is_key_value_pair() const noexcept;
|
|
|
|
/** Returns `true` if the initializer list consists only of key-value pairs
|
|
|
|
This function returns `true` if @ref is_key_value_pair()
|
|
is true for every element in the initializer list.
|
|
|
|
@par Complexity
|
|
|
|
Linear in `init.size()`.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
|
|
@param init The initializer list to inspect.
|
|
*/
|
|
static
|
|
BOOST_JSON_DECL
|
|
bool
|
|
maybe_object(
|
|
std::initializer_list<value> init) noexcept;
|
|
|
|
//------------------------------------------------------
|
|
//
|
|
// Observers
|
|
//
|
|
//------------------------------------------------------
|
|
|
|
/** Returns the kind of this JSON value
|
|
|
|
This function returns the discriminating enumeration
|
|
constant of type @ref json::kind corresponding to the type
|
|
of value held in the union.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
json::kind
|
|
kind() const noexcept
|
|
{
|
|
return kind_;
|
|
}
|
|
|
|
/** Returns true if this is an object
|
|
|
|
This function returns `true` if
|
|
@ref kind() equals `kind::object`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_object() const noexcept
|
|
{
|
|
return kind_ == json::kind::object;
|
|
}
|
|
|
|
/** Returns true if this is an array
|
|
|
|
This function returns `true` if
|
|
@ref kind() equals `kind::array`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_array() const noexcept
|
|
{
|
|
return kind_ == json::kind::array;
|
|
}
|
|
|
|
/** Returns true if this is a string
|
|
|
|
This function returns `true` if
|
|
@ref kind() equals `kind::string`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_string() const noexcept
|
|
{
|
|
return kind_ == json::kind::string;
|
|
}
|
|
|
|
/** Returns true if this is a number
|
|
|
|
This function returns `true` if
|
|
@ref kind() equals `kind::number`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_number() const noexcept
|
|
{
|
|
return kind_ == json::kind::number;
|
|
}
|
|
|
|
/** Returns true if this is a boolean
|
|
|
|
This function returns `true` if
|
|
@ref kind() equals `kind::boolean`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_bool() const noexcept
|
|
{
|
|
return kind_ == json::kind::boolean;
|
|
}
|
|
|
|
/** Returns true if this is a null
|
|
|
|
This function returns `true` if
|
|
@ref kind() equals `kind::null`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_null() const noexcept
|
|
{
|
|
return kind_ == json::kind::null;
|
|
}
|
|
|
|
/** Returns true if this is not an array or object
|
|
|
|
This function returns `true` if
|
|
@ref kind() is neither `kind::object` nor
|
|
`kind::array`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_primitive() const noexcept
|
|
{
|
|
return
|
|
kind_ != json::kind::object &&
|
|
kind_ != json::kind::array;
|
|
}
|
|
|
|
/** Returns true if this is an array or object
|
|
|
|
This function returns `true` if
|
|
@ref kind() is either `kind::object` or
|
|
`kind::array`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
*/
|
|
bool
|
|
is_structured() const noexcept
|
|
{
|
|
return
|
|
kind_ == json::kind::object ||
|
|
kind_ == json::kind::array;
|
|
}
|
|
|
|
//------------------------------------------------------
|
|
//
|
|
// Accessors
|
|
//
|
|
//------------------------------------------------------
|
|
|
|
/** Return the storage associated with the value.
|
|
|
|
This returns a pointer to the storage object
|
|
that was used to construct the value.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
BOOST_JSON_DECL
|
|
storage_ptr const&
|
|
get_storage() const noexcept;
|
|
|
|
/** Return a pointer to an object, or nullptr.
|
|
|
|
If @ref kind() returns `kind::object`,
|
|
returns a pointer to the object. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
object*
|
|
if_object() noexcept
|
|
{
|
|
if(kind_ == json::kind::object)
|
|
return &obj_;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to an object, or nullptr.
|
|
|
|
If @ref kind() returns `kind::object`,
|
|
returns a pointer to the object. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
object const*
|
|
if_object() const noexcept
|
|
{
|
|
if(kind_ == json::kind::object)
|
|
return &obj_;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to an array, or nullptr.
|
|
|
|
If @ref kind() returns `kind::array`,
|
|
returns a pointer to the array. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
array*
|
|
if_array() noexcept
|
|
{
|
|
if(kind_ == json::kind::array)
|
|
return &arr_;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to an array, or nullptr.
|
|
|
|
If @ref kind() returns `kind::array`,
|
|
returns a pointer to the array. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
array const*
|
|
if_array() const noexcept
|
|
{
|
|
if(kind_ == json::kind::array)
|
|
return &arr_;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to a string, or nullptr.
|
|
|
|
If @ref kind() returns `kind::string`,
|
|
returns a pointer to the string. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
string*
|
|
if_string() noexcept
|
|
{
|
|
if(kind_ == json::kind::string)
|
|
return &str_;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to a string, or nullptr.
|
|
|
|
If @ref kind() returns `kind::string`,
|
|
returns a pointer to the string. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
string const*
|
|
if_string() const noexcept
|
|
{
|
|
if(kind_ == json::kind::string)
|
|
return &str_;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to a number, or nullptr.
|
|
|
|
If @ref kind() returns `kind::number`,
|
|
returns a pointer to the number. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
number*
|
|
if_number() noexcept
|
|
{
|
|
if(kind_ == json::kind::number)
|
|
return &sca_.num;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to a number, or nullptr.
|
|
|
|
If @ref kind() returns `kind::number`,
|
|
returns a pointer to the number. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
number const*
|
|
if_number() const noexcept
|
|
{
|
|
if(kind_ == json::kind::number)
|
|
return &sca_.num;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to a bool, or nullptr.
|
|
|
|
If @ref kind() returns `kind::boolean`,
|
|
returns a pointer to the `bool`. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
bool*
|
|
if_bool() noexcept
|
|
{
|
|
if(kind_ == json::kind::boolean)
|
|
return &sca_.b;
|
|
return nullptr;
|
|
}
|
|
|
|
/** Return a pointer to a bool, or nullptr.
|
|
|
|
If @ref kind() returns `kind::boolean`,
|
|
returns a pointer to the `bool`. Otherwise,
|
|
returns `nullptr`.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
No-throw guarantee.
|
|
*/
|
|
bool const*
|
|
if_bool() const noexcept
|
|
{
|
|
if(kind_ == json::kind::boolean)
|
|
return &sca_.b;
|
|
return nullptr;
|
|
}
|
|
|
|
//------------------------------------------------------
|
|
|
|
/** Return a reference to the object, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::object`,
|
|
returns a reference to the object. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not an object.
|
|
*/
|
|
object&
|
|
as_object()
|
|
{
|
|
if(kind_ != json::kind::object)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_object));
|
|
return obj_;
|
|
}
|
|
|
|
/** Return a reference to the object, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::object`,
|
|
returns a reference to the object. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not an object.
|
|
*/
|
|
object const&
|
|
as_object() const
|
|
{
|
|
if(kind_ != json::kind::object)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_object));
|
|
return obj_;
|
|
}
|
|
|
|
/** Return a reference to the array, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::array`,
|
|
returns a reference to the array. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not an array.
|
|
*/
|
|
array&
|
|
as_array()
|
|
{
|
|
if(kind_ != json::kind::array)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_array));
|
|
return arr_;
|
|
}
|
|
|
|
/** Return a reference to the array, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::array`,
|
|
returns a reference to the array. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not an array.
|
|
*/
|
|
array const&
|
|
as_array() const
|
|
{
|
|
if(kind_ != json::kind::array)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_array));
|
|
return arr_;
|
|
}
|
|
|
|
/** Return a reference to the string, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::string`,
|
|
returns a reference to the string. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not a string.
|
|
*/
|
|
string&
|
|
as_string()
|
|
{
|
|
if(kind_ != json::kind::string)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_string));
|
|
return str_;
|
|
}
|
|
|
|
/** Return a reference to the string, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::string`,
|
|
returns a reference to the string. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not a string.
|
|
*/
|
|
string const&
|
|
as_string() const
|
|
{
|
|
if(kind_ != json::kind::string)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_string));
|
|
return str_;
|
|
}
|
|
|
|
/** Return a reference to the number, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::number`,
|
|
returns a reference to the number. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not a number.
|
|
*/
|
|
number&
|
|
as_number()
|
|
{
|
|
if(kind_ != json::kind::number)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_number));
|
|
return sca_.num;
|
|
}
|
|
|
|
/** Return a reference to the number, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::number`,
|
|
returns a reference to the number. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not a number.
|
|
*/
|
|
number const&
|
|
as_number() const
|
|
{
|
|
if(kind_ != json::kind::number)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_number));
|
|
return sca_.num;
|
|
}
|
|
|
|
/** Return a reference to the bool, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::boolean`,
|
|
returns a reference to the `bool`. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not a boolean.
|
|
*/
|
|
bool&
|
|
as_bool()
|
|
{
|
|
if(kind_ != json::kind::boolean)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_bool));
|
|
return sca_.b;
|
|
}
|
|
|
|
/** Return a reference to the bool, or throw an exception.
|
|
|
|
If @ref kind() returns `kind::boolean`,
|
|
returns a reference to the `bool`. Otherwise,
|
|
throws an exception.
|
|
|
|
@par Complexity
|
|
|
|
Constant.
|
|
|
|
@par Exception Safety
|
|
|
|
Strong guarantee.
|
|
|
|
@throw system_error if `*this` is not a boolean.
|
|
*/
|
|
bool const&
|
|
as_bool() const
|
|
{
|
|
if(kind_ != json::kind::boolean)
|
|
BOOST_JSON_THROW(
|
|
system_error(
|
|
error::not_bool));
|
|
return sca_.b;
|
|
}
|
|
|
|
//------------------------------------------------------
|
|
|
|
private:
|
|
BOOST_JSON_DECL
|
|
void
|
|
construct(
|
|
json::kind, storage_ptr) noexcept;
|
|
};
|
|
|
|
} // json
|
|
} // boost
|
|
|
|
#include <boost/json/impl/array.hpp>
|
|
#include <boost/json/impl/object.hpp>
|
|
#ifdef BOOST_JSON_HEADER_ONLY
|
|
#include <boost/json/impl/array.ipp>
|
|
#include <boost/json/impl/object.ipp>
|
|
#endif
|
|
|
|
// These must come after array and object
|
|
#include <boost/json/impl/value.hpp>
|
|
#ifdef BOOST_JSON_HEADER_ONLY
|
|
#include <boost/json/impl/value.ipp>
|
|
#endif
|
|
|
|
#endif
|