From 59679826b01b1d70a6a5cb307e3b549b5d943930 Mon Sep 17 00:00:00 2001 From: Daniel Parker Date: Thu, 24 Oct 2024 21:02:44 -0400 Subject: [PATCH] Doc update --- doc/ref/corelib/json/allocators.md | 91 ++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/doc/ref/corelib/json/allocators.md b/doc/ref/corelib/json/allocators.md index 58092edbc..0ddc7c562 100644 --- a/doc/ref/corelib/json/allocators.md +++ b/doc/ref/corelib/json/allocators.md @@ -14,15 +14,43 @@ A long string, byte string, array or object contains a pointer to underlying sto 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 +#### Propagation -`basic_json` copy construction +The allocator applies not only to a `basic_json`'s data member, but also to its data member's elements. For example: + +```cpp +char buffer[1024]; +std::pmr::monotonic_buffer_resource pool{ std::data(buffer), std::size(buffer) }; +std::pmr::polymorphic_allocator alloc(&pool); + +std::string key1 = "KeyToLongForShortString"; +std::string value1 = "string too long for short string"; +std::string key2 = "AnotherKeyToLongForShortString"; +std::string value2 = "another string too long for short string"; + +jsoncons::pmr::json j{ jsoncons::json_object_arg, alloc }; +assert(j.get_allocator().resource() == &pool); +j[key1] = value1; +j.try_emplace(key2, value2); +auto it = std::search(std::begin(buffer), std::end(buffer), key1.begin(), key1.end()); +assert(it != std::end(buffer)); +it = std::search(std::begin(buffer), std::end(buffer), value1.begin(), value1.end()); +assert(it != std::end(buffer)); +it = std::search(std::begin(buffer), std::end(buffer), key2.begin(), key2.end()); +assert(it != std::end(buffer)); +it = std::search(std::begin(buffer), std::end(buffer), value2.begin(), value2.end()); +assert(it != std::end(buffer)); +``` + +#### Copy constructor + +`basic_json` copy constructor ``` Json j1(j); ``` -constructs `j1` from `j`. If `j` is a long string, bytes string, array or object, +constructs `j1` from `j`. If `j` holds a long string, bytes string, array or object, copy construction applies allocator traits `select_on_container_copy_construction` to the allocator from `j` (since 0.178.0) For example: @@ -33,7 +61,7 @@ std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); -assert(j.get_allocator() == alloc); +assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(j); assert(j1 == j); @@ -42,7 +70,36 @@ assert(j1.get_allocator() == std::allocator_traits{}); // expected result for pmr allocators ``` -#### Move construction +#### Allocator-extended copy constructor + +`basic_json` copy constructor + +``` +Json j1(j, alloc); +``` + +constructs `j1` from `j`. If `j` holds a long string, bytes string, array or object, +copy construction uses allocator `alloc` for allocating storage, otherwise `alloc` is ignored. For example: + +```cpp +char buffer1[1024]; +std::pmr::monotonic_buffer_resource pool1{ std::data(buffer1), std::size(buffer1) }; +std::pmr::polymorphic_allocator alloc1(&pool1); + +char buffer2[1024]; +std::pmr::monotonic_buffer_resource pool2{ std::data(buffer2), std::size(buffer2) }; +std::pmr::polymorphic_allocator alloc2(&pool2); + +jsoncons::pmr::json j{ "String too long for short string", alloc1 }; +assert(j.is_string()); +assert(j.get_allocator().resource() == &pool1); + +jsoncons::pmr::json j1(j, alloc2); +assert(j1 == j); +assert(j1.get_allocator().resource() == &pool2); +``` + +#### Move constructor `basic_json` move construction @@ -54,17 +111,17 @@ initializes `j1` with the contents of `j`, which is either a pointer or a trivia and changes the value in `j` to `null`. For example: ``` -char buffer[1024] = {}; +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}; assert(j.is_string()); -assert(alloc == j.get_allocator()); +assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1(std::move(j)); assert(j1.is_string()); -assert(alloc == j1.get_allocator()); +assert(j1.get_allocator().resource() == &pool); assert(j.is_null()); ``` @@ -87,13 +144,27 @@ std::pmr::polymorphic_allocator alloc(&pool); jsoncons::pmr::json j{ "String too long for short string", alloc }; assert(j.is_string()); -assert(alloc == j.get_allocator()); +assert(j.get_allocator().resource() == &pool); jsoncons::pmr::json j1{10}; assert(j1.is_number()); j1 = std::move(j); assert(j1.is_string()); -assert(alloc == j1.get_allocator()); +assert(j1.get_allocator().resource() == &pool); assert(j.is_number()); ``` + +#### Resources + +[An allocator-aware variant type](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3153r0.html) + +[C++ named requirements: Allocator](https://en.cppreference.com/w/cpp/named_req/Allocator) + +[std::allocator_traits](https://en.cppreference.com/w/cpp/memory/allocator_traits) + +[std::pmr::polymorphic_allocator](https://en.cppreference.com/w/cpp/memory/polymorphic_allocator) + +[std::scoped_allocator_adaptor](https://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor) + +