mirror of
https://github.com/nlohmann/json.git
synced 2026-10-02 20:50:32 +00:00
basic_json::swap() (and the friend swap() and the pre-C++20 std::swap overload that forward to it) only exchanged m_data.m_type/m_data.m_value, leaving each value's json_base_class_t subobject in place. This is inconsistent with the copy and move constructors and copy assignment, which all carry the base class along with the value, so after a.swap(b) any metadata stored in a CustomBaseClass ended up attached to the wrong value. Algorithms that mix swap() with moves, such as std::sort, scrambled the metadata across the whole container. Fix the member swap() to also exchange the json_base_class_t subobject and extend the noexcept specifications of swap() and the friend swap() accordingly. Fixes #5653. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
6.7 KiB
6.7 KiB
nlohmann::basic_json::swap
// (1)
void swap(reference other) noexcept (
std::is_nothrow_move_constructible<value_t>::value &&
std::is_nothrow_move_assignable<value_t>::value &&
std::is_nothrow_move_constructible<json_value>::value &&
std::is_nothrow_move_assignable<json_value>::value &&
std::is_nothrow_move_constructible<json_base_class_t>::value &&
std::is_nothrow_move_assignable<json_base_class_t>::value
);
// (2)
friend void swap(reference left, reference right) noexcept (
std::is_nothrow_move_constructible<value_t>::value &&
std::is_nothrow_move_assignable<value_t>::value &&
std::is_nothrow_move_constructible<json_value>::value &&
std::is_nothrow_move_assignable<json_value>::value &&
std::is_nothrow_move_constructible<json_base_class_t>::value &&
std::is_nothrow_move_assignable<json_base_class_t>::value
);
// (3)
void swap(array_t& other);
// (4)
void swap(object_t& other);
// (5)
void swap(string_t& other);
// (6)
void swap(binary_t& other);
// (7)
void swap(typename binary_t::container_type& other);
- Exchanges the contents of the JSON value with those of
other. Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. If macroJSON_DIAGNOSTIC_POSITIONSis defined to#!cpp 1, thestart_pos()/end_pos()diagnostic positions are exchanged along with the value. Thejson_base_class_tsubobject is exchanged along with the value as well, the same way it is copied or moved by the copy/move constructors and assignment operators. - Exchanges the contents of the JSON value from
leftwith those ofright. Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Implemented as a friend function callable via ADL. If macroJSON_DIAGNOSTIC_POSITIONSis defined to#!cpp 1, thestart_pos()/end_pos()diagnostic positions are exchanged along with the value. Thejson_base_class_tsubobject is exchanged along with the value as well, the same way it is copied or moved by the copy/move constructors and assignment operators. - Exchanges the contents of a JSON array with those of
other. Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. - Exchanges the contents of a JSON object with those of
other. Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. - Exchanges the contents of a JSON string with those of
other. Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. - Exchanges the contents of a binary value with those of
other. Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. - Exchanges the contents of a binary value with those of
other. Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Unlike version (6), no binary subtype is involved.
Parameters
other(in, out)- value to exchange the contents with
left(in, out)- value to exchange the contents with
right(in, out)- value to exchange the contents with
Exceptions
- No-throw guarantee: this function never throws exceptions.
- No-throw guarantee: this function never throws exceptions.
- Throws
type_error.310if called on JSON values other than arrays; example:"cannot use swap(array_t&) with boolean" - Throws
type_error.310if called on JSON values other than objects; example:"cannot use swap(object_t&) with boolean" - Throws
type_error.310if called on JSON values other than strings; example:"cannot use swap(string_t&) with boolean" - Throws
type_error.310if called on JSON values other than binaries; example:"cannot use swap(binary_t&) with boolean" - Throws
type_error.310if called on JSON values other than binaries; example:"cannot use swap(binary_t::container_type&) with boolean"
Complexity
Constant.
Examples
??? example "Example: Swap JSON value (1, 2)"
The example below shows how JSON values can be swapped with `swap()`.
```cpp
--8<-- "examples/swap__reference.cpp"
```
Output:
```json
--8<-- "examples/swap__reference.output"
```
??? example "Example: Swap array (3)"
The example below shows how arrays can be swapped with `swap()`.
```cpp
--8<-- "examples/swap__array_t.cpp"
```
Output:
```json
--8<-- "examples/swap__array_t.output"
```
??? example "Example: Swap object (4)"
The example below shows how objects can be swapped with `swap()`.
```cpp
--8<-- "examples/swap__object_t.cpp"
```
Output:
```json
--8<-- "examples/swap__object_t.output"
```
??? example "Example: Swap string (5)"
The example below shows how strings can be swapped with `swap()`.
```cpp
--8<-- "examples/swap__string_t.cpp"
```
Output:
```json
--8<-- "examples/swap__string_t.output"
```
??? example "Example: Swap binary (6)"
The example below shows how binary values can be swapped with `swap()`.
```cpp
--8<-- "examples/swap__binary_t.cpp"
```
Output:
```json
--8<-- "examples/swap__binary_t.output"
```
See also
- std::swap<basic_json>
- operator= copy assignment
- basic_json create a JSON value
Version history
- Since version 1.0.0. Exchanges the
json_base_class_tsubobject along with the value since version 3.13.0. - Since version 1.0.0. Exchanges the
json_base_class_tsubobject along with the value since version 3.13.0. - Since version 1.0.0.
- Since version 1.0.0.
- Since version 1.0.0.
- Since version 3.8.0.
- Since version 3.8.0.