mirror of
https://github.com/boostorg/json.git
synced 2025-05-12 06:01:41 +00:00
null_resource is a singleton
This commit is contained in:
parent
7bde63b316
commit
a2917e736a
@ -158,6 +158,14 @@ available when using the library:
|
|||||||
[table Functions and Types
|
[table Functions and Types
|
||||||
[ [Name] [Description] ]
|
[ [Name] [Description] ]
|
||||||
[
|
[
|
||||||
|
[__get_null_resource__]
|
||||||
|
[
|
||||||
|
Returns a pointer to a memory resource instance which
|
||||||
|
always throws an exception upon allocation. This is
|
||||||
|
used to to achieve the invariant that no parsing or
|
||||||
|
container operation will dynamically allocate memory.
|
||||||
|
]
|
||||||
|
][
|
||||||
[__is_deallocate_trivial__]
|
[__is_deallocate_trivial__]
|
||||||
[
|
[
|
||||||
A customization point allowing a memory resource type
|
A customization point allowing a memory resource type
|
||||||
@ -182,13 +190,6 @@ available when using the library:
|
|||||||
freed until the resource is destroyed, making it fast for
|
freed until the resource is destroyed, making it fast for
|
||||||
parsing but not suited for performing modifications.
|
parsing but not suited for performing modifications.
|
||||||
]
|
]
|
||||||
][
|
|
||||||
[__null_resource__]
|
|
||||||
[
|
|
||||||
A memory resource always throws an exception upon allocation.
|
|
||||||
This is used to to achieve the invariant that no parsing
|
|
||||||
or container operation will dynamically allocate memory.
|
|
||||||
]
|
|
||||||
][
|
][
|
||||||
[__polymorphic_allocator__]
|
[__polymorphic_allocator__]
|
||||||
[
|
[
|
||||||
@ -285,11 +286,12 @@ To use the resource, construct it with a local buffer:
|
|||||||
|
|
||||||
[heading Null Resource]
|
[heading Null Resource]
|
||||||
|
|
||||||
The __null_resource__ can only be default constructed. It offers a simple
|
The function __get_null_resource__ returns a global instance of the
|
||||||
invariant: all calls to allocate will throw the exception `std::bad_alloc`.
|
null resource. This resource offers a simple invariant: all calls to
|
||||||
An instance of the null resource can be used to make parsing guarantee
|
allocate will throw the exception `std::bad_alloc`. An instance of
|
||||||
that allocations from the heap are never made. This is explored in more
|
the null resource can be used to make parsing guarantee that
|
||||||
detail in a later section.
|
allocations from the heap are never made. This is explored
|
||||||
|
in more detail in a later section.
|
||||||
|
|
||||||
[/-----------------------------------------------------------------------------]
|
[/-----------------------------------------------------------------------------]
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
[def __error_code__ [link json.ref.boost__json__error_code `error_code`]]
|
[def __error_code__ [link json.ref.boost__json__error_code `error_code`]]
|
||||||
[def __error_condition__ [link json.ref.boost__json__error_condition `error_condition`]]
|
[def __error_condition__ [link json.ref.boost__json__error_condition `error_condition`]]
|
||||||
[def __get__ [link json.ref.boost__json__get `get`]]
|
[def __get__ [link json.ref.boost__json__get `get`]]
|
||||||
|
[def __get_null_resource__ [link json.ref.boost__json__get_null_resource `get_null_resource`]]
|
||||||
[def __has_value_from__ [link json.ref.boost__json__has_value_from `has_value_from`]]
|
[def __has_value_from__ [link json.ref.boost__json__has_value_from `has_value_from`]]
|
||||||
[def __has_value_to__ [link json.ref.boost__json__has_value_to `has_value_to`]]
|
[def __has_value_to__ [link json.ref.boost__json__has_value_to `has_value_to`]]
|
||||||
[def __is_deallocate_trivial__ [link json.ref.boost__json__is_deallocate_trivial `is_deallocate_trivial`]]
|
[def __is_deallocate_trivial__ [link json.ref.boost__json__is_deallocate_trivial `is_deallocate_trivial`]]
|
||||||
@ -60,7 +61,6 @@
|
|||||||
[def __make_counted_resource__ [link json.ref.boost__json__make_counted_resource `make_counted_resource`]]
|
[def __make_counted_resource__ [link json.ref.boost__json__make_counted_resource `make_counted_resource`]]
|
||||||
[def __memory_resource__ [link json.ref.boost__json__memory_resource `memory_resource`]]
|
[def __memory_resource__ [link json.ref.boost__json__memory_resource `memory_resource`]]
|
||||||
[def __monotonic_resource__ [link json.ref.boost__json__monotonic_resource `monotonic_resource`]]
|
[def __monotonic_resource__ [link json.ref.boost__json__monotonic_resource `monotonic_resource`]]
|
||||||
[def __null_resource__ [link json.ref.boost__json__null_resource `null_resource`]]
|
|
||||||
[def __number_cast__ [link json.ref.boost__json__number_cast `number_cast`]]
|
[def __number_cast__ [link json.ref.boost__json__number_cast `number_cast`]]
|
||||||
[def __object__ [link json.ref.boost__json__object `object`]]
|
[def __object__ [link json.ref.boost__json__object `object`]]
|
||||||
[def __parse__ [link json.ref.boost__json__parse `parse`]]
|
[def __parse__ [link json.ref.boost__json__parse `parse`]]
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
<member><link linkend="json.ref.boost__json__basic_parser">basic_parser</link></member>
|
<member><link linkend="json.ref.boost__json__basic_parser">basic_parser</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__key_value_pair">key_value_pair</link></member>
|
<member><link linkend="json.ref.boost__json__key_value_pair">key_value_pair</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__monotonic_resource">monotonic_resource</link></member>
|
<member><link linkend="json.ref.boost__json__monotonic_resource">monotonic_resource</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__null_resource">null_resource</link></member>
|
|
||||||
<member><link linkend="json.ref.boost__json__object">object</link></member>
|
<member><link linkend="json.ref.boost__json__object">object</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__parser">parser</link></member>
|
<member><link linkend="json.ref.boost__json__parser">parser</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__parse_options">parse_options</link></member>
|
<member><link linkend="json.ref.boost__json__parse_options">parse_options</link></member>
|
||||||
@ -41,6 +40,7 @@
|
|||||||
<bridgehead renderas="sect3">Functions</bridgehead>
|
<bridgehead renderas="sect3">Functions</bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<simplelist type="vert" columns="1">
|
||||||
<member><link linkend="json.ref.boost__json__get">get</link></member>
|
<member><link linkend="json.ref.boost__json__get">get</link></member>
|
||||||
|
<member><link linkend="json.ref.boost__json__get_null_resource">get_null_resource</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__make_counted_resource">make_counted_resource</link></member>
|
<member><link linkend="json.ref.boost__json__make_counted_resource">make_counted_resource</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__number_cast">number_cast</link></member>
|
<member><link linkend="json.ref.boost__json__number_cast">number_cast</link></member>
|
||||||
<member><link linkend="json.ref.boost__json__parse">parse</link></member>
|
<member><link linkend="json.ref.boost__json__parse">parse</link></member>
|
||||||
|
@ -67,8 +67,7 @@ struct FuzzHelper {
|
|||||||
void useDynLess() {
|
void useDynLess() {
|
||||||
// this is on the heap because the size is chosen dynamically
|
// this is on the heap because the size is chosen dynamically
|
||||||
std::unique_ptr<unsigned char[]> temp(new unsigned char[memlimit1]);
|
std::unique_ptr<unsigned char[]> temp(new unsigned char[memlimit1]);
|
||||||
null_resource nr;
|
parser p(get_null_resource(),
|
||||||
parser p(&nr,
|
|
||||||
opt,
|
opt,
|
||||||
temp.get(),
|
temp.get(),
|
||||||
memlimit1);
|
memlimit1);
|
||||||
|
@ -15,33 +15,86 @@
|
|||||||
|
|
||||||
BOOST_JSON_NS_BEGIN
|
BOOST_JSON_NS_BEGIN
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
/** A resource which always fails.
|
||||||
|
|
||||||
|
This memory resource always throws the exception
|
||||||
|
`std::bad_alloc` in calls to `allocate`.
|
||||||
|
*/
|
||||||
|
class null_resource final
|
||||||
|
: public memory_resource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Copy constructor (deleted)
|
||||||
|
null_resource(
|
||||||
|
null_resource const&) = delete;
|
||||||
|
|
||||||
|
/// Copy assignment (deleted)
|
||||||
|
null_resource& operator=(
|
||||||
|
null_resource const&) = delete;
|
||||||
|
|
||||||
|
/** Destructor
|
||||||
|
|
||||||
|
This destroys the resource.
|
||||||
|
|
||||||
|
@par Complexity
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
@part Exception Safety
|
||||||
|
No-throw guarantee.
|
||||||
|
*/
|
||||||
|
~null_resource() noexcept = default;
|
||||||
|
|
||||||
|
/** Constructor
|
||||||
|
|
||||||
|
This constructs the resource.
|
||||||
|
|
||||||
|
@par Complexity
|
||||||
|
Constant.
|
||||||
|
|
||||||
|
@par Exception Safety
|
||||||
|
No-throw guarantee.
|
||||||
|
*/
|
||||||
|
/** @{ */
|
||||||
|
null_resource() noexcept = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
void*
|
void*
|
||||||
null_resource::
|
|
||||||
do_allocate(
|
do_allocate(
|
||||||
std::size_t,
|
std::size_t,
|
||||||
std::size_t)
|
std::size_t) override
|
||||||
{
|
{
|
||||||
detail::throw_bad_alloc(
|
detail::throw_bad_alloc(
|
||||||
BOOST_CURRENT_LOCATION);
|
BOOST_CURRENT_LOCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
null_resource::
|
|
||||||
do_deallocate(
|
do_deallocate(
|
||||||
void*,
|
void*,
|
||||||
std::size_t,
|
std::size_t,
|
||||||
std::size_t)
|
std::size_t) override
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
null_resource::
|
|
||||||
do_is_equal(
|
do_is_equal(
|
||||||
memory_resource const& mr) const noexcept
|
memory_resource const& mr
|
||||||
|
) const noexcept override
|
||||||
{
|
{
|
||||||
return this == &mr;
|
return this == &mr;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
|
memory_resource*
|
||||||
|
get_null_resource() noexcept
|
||||||
|
{
|
||||||
|
static detail::null_resource mr;
|
||||||
|
return &mr;
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_JSON_NS_END
|
BOOST_JSON_NS_END
|
||||||
|
|
||||||
|
@ -15,41 +15,10 @@
|
|||||||
|
|
||||||
BOOST_JSON_NS_BEGIN
|
BOOST_JSON_NS_BEGIN
|
||||||
|
|
||||||
//----------------------------------------------------------
|
/** Return a pointer to the null resource.
|
||||||
|
|
||||||
/** A resource which always fails.
|
|
||||||
|
|
||||||
This memory resource always throws the exception
|
This memory resource always throws the exception
|
||||||
`std::bad_alloc` in calls to `allocate`.
|
`std::bad_alloc` in calls to `allocate`.
|
||||||
*/
|
|
||||||
class BOOST_JSON_CLASS_DECL
|
|
||||||
null_resource final
|
|
||||||
: public memory_resource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// Copy constructor (deleted)
|
|
||||||
null_resource(
|
|
||||||
null_resource const&) = delete;
|
|
||||||
|
|
||||||
/// Copy assignment (deleted)
|
|
||||||
null_resource& operator=(
|
|
||||||
null_resource const&) = delete;
|
|
||||||
|
|
||||||
/** Destructor
|
|
||||||
|
|
||||||
This destroys the resource.
|
|
||||||
|
|
||||||
@par Complexity
|
|
||||||
Constant.
|
|
||||||
|
|
||||||
@part Exception Safety
|
|
||||||
No-throw guarantee.
|
|
||||||
*/
|
|
||||||
~null_resource() noexcept = default;
|
|
||||||
|
|
||||||
/** Constructor
|
|
||||||
|
|
||||||
This constructs the resource.
|
|
||||||
|
|
||||||
@par Complexity
|
@par Complexity
|
||||||
Constant.
|
Constant.
|
||||||
@ -57,35 +26,9 @@ public:
|
|||||||
@par Exception Safety
|
@par Exception Safety
|
||||||
No-throw guarantee.
|
No-throw guarantee.
|
||||||
*/
|
*/
|
||||||
/** @{ */
|
BOOST_JSON_DECL
|
||||||
null_resource() noexcept = default;
|
memory_resource*
|
||||||
|
get_null_resource() noexcept;
|
||||||
protected:
|
|
||||||
#ifndef BOOST_JSON_DOCS
|
|
||||||
void*
|
|
||||||
do_allocate(
|
|
||||||
std::size_t n,
|
|
||||||
std::size_t align) override;
|
|
||||||
|
|
||||||
void
|
|
||||||
do_deallocate(
|
|
||||||
void* p,
|
|
||||||
std::size_t n,
|
|
||||||
std::size_t align) override;
|
|
||||||
|
|
||||||
bool
|
|
||||||
do_is_equal(
|
|
||||||
memory_resource const& mr
|
|
||||||
) const noexcept override;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_deallocate_trivial<
|
|
||||||
null_resource>
|
|
||||||
{
|
|
||||||
static constexpr bool value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
BOOST_JSON_NS_END
|
BOOST_JSON_NS_END
|
||||||
|
|
||||||
|
@ -1053,7 +1053,14 @@ public:
|
|||||||
return *this = value(init, storage());
|
return *this = value(init, storage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Assignment.
|
/** Assignment
|
||||||
|
|
||||||
|
Assigns `t` to `*this`.
|
||||||
|
|
||||||
|
@par Effects
|
||||||
|
@code
|
||||||
|
*this = value( std::forward<T>(t), this->storage() );
|
||||||
|
@endcode
|
||||||
|
|
||||||
@par Constraints
|
@par Constraints
|
||||||
@code
|
@code
|
||||||
|
@ -195,9 +195,11 @@ parser p(
|
|||||||
template< class Handler >
|
template< class Handler >
|
||||||
void do_rpc( string_view s, Handler&& handler )
|
void do_rpc( string_view s, Handler&& handler )
|
||||||
{
|
{
|
||||||
null_resource mr1; // The null resource guarantees we will never dynamically allocate
|
|
||||||
unsigned char temp[ 4096 ]; // The parser will use this storage for its temporary needs
|
unsigned char temp[ 4096 ]; // The parser will use this storage for its temporary needs
|
||||||
parser p( &mr1, parse_options(), temp ); // Construct a strict parser using the temp buffer and no dynamic memory
|
parser p( // Construct a strict parser using the temp buffer and no dynamic memory
|
||||||
|
get_null_resource(), // The null resource guarantees we will never dynamically allocate
|
||||||
|
parse_options(), // Default constructed parse options allow only standard JSON
|
||||||
|
temp );
|
||||||
|
|
||||||
unsigned char buf[ 16384 ]; // Now we need a buffer to hold the actual JSON values
|
unsigned char buf[ 16384 ]; // Now we need a buffer to hold the actual JSON values
|
||||||
static_resource mr2( buf ); // The static resource is monotonic, using only a caller-provided buffer
|
static_resource mr2( buf ); // The static resource is monotonic, using only a caller-provided buffer
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
// Test that header file is self-contained.
|
// Test that header file is self-contained.
|
||||||
#include <boost/json/null_resource.hpp>
|
#include <boost/json/null_resource.hpp>
|
||||||
|
|
||||||
|
#include <boost/json/storage_ptr.hpp>
|
||||||
|
|
||||||
#include "test_suite.hpp"
|
#include "test_suite.hpp"
|
||||||
|
|
||||||
BOOST_JSON_NS_BEGIN
|
BOOST_JSON_NS_BEGIN
|
||||||
@ -20,17 +22,15 @@ public:
|
|||||||
void
|
void
|
||||||
test()
|
test()
|
||||||
{
|
{
|
||||||
null_resource mr;
|
auto& mr = *get_null_resource();
|
||||||
BOOST_TEST_THROWS(
|
BOOST_TEST_THROWS(
|
||||||
mr.allocate(16),
|
mr.allocate(16),
|
||||||
std::bad_alloc);
|
std::bad_alloc);
|
||||||
char buf[128];
|
char buf[128];
|
||||||
// no-op
|
// no-op
|
||||||
mr.deallocate(&buf[0], 128);
|
mr.deallocate(&buf[0], 128);
|
||||||
|
BOOST_TEST(
|
||||||
BOOST_TEST(mr == mr);
|
mr == *get_null_resource());
|
||||||
null_resource mr2;
|
|
||||||
BOOST_TEST(mr != mr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user