diff --git a/doc/ref/corelib/basic_json.md b/doc/ref/corelib/basic_json.md index f934b5876..a92a233cd 100644 --- a/doc/ref/corelib/basic_json.md +++ b/doc/ref/corelib/basic_json.md @@ -20,16 +20,16 @@ namespace pmr { ``` A `basic_json` is a union type that can hold one of a number of possible data members, -some that require an allocator (a pointer to a long string, byte string, array, or object), -and other trivially copyable ones that do not (an empty object, short string, number, boolean, or null). +some that require an allocator (a long string, byte string, array, or object), +and others that are trivially copyable that do not (an empty object, short string, number, boolean, or null). The data member may be tagged with a [semantic_tag](semantic_tag.md) that provides additional information about its value. The sizeof a `basic_json` regardless of its template parameters -is 16 bytes. +is normally 16 bytes. A `basic_json` is allocator-aware, and supports allocator propagation to allocator-aware arrays or objects. Every constructor has a version that accepts an allocator argument. -The allocator is used to allocate memory for a long string, byte string, array, or object, -and it is retained in the long string, byte string, array, or object itself. +A long string, byte string, array or object contains a pointer to underlying storage, +the allocator is used to allocate that storage, and it is retained in that storage. For other data members the allocator argument is ignored. When assigned a new `basic_json` value, the old value is overwritten. The member data type of the new value may be different diff --git a/doc/ref/corelib/json/allocators.md b/doc/ref/corelib/json/allocators.md index 69088b28f..b2f417923 100644 --- a/doc/ref/corelib/json/allocators.md +++ b/doc/ref/corelib/json/allocators.md @@ -1,6 +1,5 @@ ### Allocators - A `basic_json` has an `Allocator` template parameter and an `allocator_type` member that indicates that it is allocator aware. `Allocator` must be a Scoped Allocator, that is, an allocator that applies not only to a `basic_json`'s data member, but also to its data member's elements. @@ -10,10 +9,36 @@ or a s Non-propagating stateful allocators, such as the [Boost.Interprocess allocators](https://www.boost.org/doc/libs/1_82_0/doc/html/interprocess/allocators_containers.html#interprocess.allocators_containers.allocator_introduction), must be wrapped by a [std::scoped_allocator_adaptor](https://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor). -Every constructor has a version that accepts an allocator argument. -The allocator is used to allocate memory for a long string, byte string, array, or object, -and it is retained in the long string, byte string, array, or object itself. -For other data members the allocator argument is ignored. +Every constructor has a version that accepts an allocator argument. +A long string, byte string, array or object contains a pointer to underlying storage, +the allocator is used to allocate that storage, and it is retained in that storage. +For other data members the allocator argument is ignored. + +#### Copy construction + +`basic_json` copy construction + +``` +Json j1(j); +``` + +constructs `j1` from `j`. If `j` is a long string, bytes string, array or object, +copy construction uses allocator traits `select_on_container_copy_construction` to obtain +an allocator (since 0.178.0) For example: + +```cpp +char buffer[1024]; +std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; +std::pmr::polymorphic_allocator alloc(&pool); + +jsoncons::pmr::json j{ "String too long for short string", alloc }; + +jsoncons::pmr::json j1(j); +assert(j1.is_string()); +assert(j1.get_allocator() == std::allocator_traits>:: + select_on_container_copy_construction(j.get_allocator())); +assert(j1.get_allocator() == std::pmr::polymorphic_allocator{}); // expected result for pmr allocators +``` #### Move construction @@ -23,7 +48,8 @@ For other data members the allocator argument is ignored. Json j1(std::move(j)); ``` -initializes `j1` with the pointer or non-pointer value in `j`, and changes the value in `j` to `null`. For example: +initializes `j1` with the contents of `j`, which is either a pointer or a trivially copyable value, +and changes the value in `j` to `null`. For example: ``` char buffer[1024] = {}; @@ -42,14 +68,15 @@ assert(j.is_null()); #### Move assignment -If either `j` or `j1` hold pointer values, `basic_json` move assignment +If either `j` or `j1` are a long string, byte string, array, or object, `basic_json` move assignment ``` j1 = std::move(j); ``` -swaps the two data member values. If both `j` and `j1` hold non-pointer values, -move assignment copies `j`'s value to `j1` and leaves `j` unchanged. For example: +swaps the two data member values, such that two pointers are swapped or a pointer and a +trivially copyable value are swapped. Otherwise, move assignment copies `j`'s value to `j1` +and leaves `j` unchanged. For example: ```cpp char buffer[1024];