From 279d7570312bb28a509962d0b12d1c51c1b16e44 Mon Sep 17 00:00:00 2001 From: nlohmann Date: Wed, 8 Jul 2026 18:19:46 +0000 Subject: [PATCH] deploy: 7c9208bfb31b2cd04871d5fe306a0b9b8673e615 --- ..md | 3 + api/adl_serializer.md | 35 + api/adl_serializer/from_json.md | 74 + api/adl_serializer/from_json/index.html | 2 +- api/adl_serializer/from_json/index.md | 157 +++ api/adl_serializer/index.html | 2 +- api/adl_serializer/index.md | 34 + api/adl_serializer/to_json.md | 43 + api/adl_serializer/to_json/index.html | 2 +- api/adl_serializer/to_json/index.md | 71 + api/basic_json.md | 338 +++++ api/basic_json/accept.md | 121 ++ api/basic_json/accept/index.html | 2 +- api/basic_json/accept/index.md | 137 ++ api/basic_json/array.md | 61 + api/basic_json/array/index.html | 2 +- api/basic_json/array/index.md | 77 ++ api/basic_json/array_t.md | 68 + api/basic_json/array_t/index.html | 2 +- api/basic_json/array_t/index.md | 73 + api/basic_json/at.md | 228 ++++ api/basic_json/at/index.html | 2 +- api/basic_json/at/index.md | 668 +++++++++ api/basic_json/back.md | 65 + api/basic_json/back/index.html | 2 +- api/basic_json/back/index.md | 105 ++ api/basic_json/basic_json.md | 402 ++++++ api/basic_json/basic_json/index.html | 2 +- api/basic_json/basic_json/index.md | 751 +++++++++++ api/basic_json/begin.md | 42 + api/basic_json/begin/index.html | 2 +- api/basic_json/begin/index.md | 55 + api/basic_json/binary.md | 66 + api/basic_json/binary/index.html | 2 +- api/basic_json/binary/index.md | 75 ++ api/basic_json/binary_t.md | 89 ++ api/basic_json/binary_t/index.html | 2 +- api/basic_json/binary_t/index.md | 88 ++ api/basic_json/boolean_t.md | 42 + api/basic_json/boolean_t/index.html | 2 +- api/basic_json/boolean_t/index.md | 50 + api/basic_json/cbegin.md | 41 + api/basic_json/cbegin/index.html | 2 +- api/basic_json/cbegin/index.md | 54 + api/basic_json/cbor_tag_handler_t.md | 42 + api/basic_json/cbor_tag_handler_t/index.html | 2 +- api/basic_json/cbor_tag_handler_t/index.md | 67 + api/basic_json/cend.md | 41 + api/basic_json/cend/index.html | 2 +- api/basic_json/cend/index.md | 57 + api/basic_json/clear.md | 58 + api/basic_json/clear/index.html | 2 +- api/basic_json/clear/index.md | 95 ++ api/basic_json/contains.md | 119 ++ api/basic_json/contains/index.html | 2 +- api/basic_json/contains/index.md | 199 +++ api/basic_json/count.md | 83 ++ api/basic_json/count/index.html | 2 +- api/basic_json/count/index.md | 115 ++ api/basic_json/crbegin.md | 41 + api/basic_json/crbegin/index.html | 2 +- api/basic_json/crbegin/index.md | 54 + api/basic_json/crend.md | 42 + api/basic_json/crend/index.html | 2 +- api/basic_json/crend/index.md | 57 + api/basic_json/default_object_comparator_t.md | 35 + .../default_object_comparator_t/index.html | 2 +- .../default_object_comparator_t/index.md | 44 + api/basic_json/diff.md | 65 + api/basic_json/diff/index.html | 2 +- api/basic_json/diff/index.md | 123 ++ api/basic_json/dump.md | 85 ++ api/basic_json/dump/index.html | 2 +- api/basic_json/dump/index.md | 173 +++ api/basic_json/emplace.md | 71 + api/basic_json/emplace/index.html | 2 +- api/basic_json/emplace/index.md | 97 ++ api/basic_json/emplace_back.md | 66 + api/basic_json/emplace_back/index.html | 2 +- api/basic_json/emplace_back/index.md | 85 ++ api/basic_json/empty.md | 66 + api/basic_json/empty/index.html | 2 +- api/basic_json/empty/index.md | 100 ++ api/basic_json/end.md | 42 + api/basic_json/end/index.html | 2 +- api/basic_json/end/index.md | 58 + api/basic_json/end_pos.md | 68 + api/basic_json/end_pos/index.html | 2 +- api/basic_json/end_pos/index.md | 163 +++ api/basic_json/erase.md | 217 +++ api/basic_json/erase/index.html | 2 +- api/basic_json/erase/index.md | 313 +++++ api/basic_json/error_handler_t.md | 42 + api/basic_json/error_handler_t/index.html | 2 +- api/basic_json/error_handler_t/index.md | 62 + api/basic_json/exception.md | 87 ++ api/basic_json/exception/index.html | 2 +- api/basic_json/exception/index.md | 103 ++ api/basic_json/find.md | 87 ++ api/basic_json/find/index.html | 2 +- api/basic_json/find/index.md | 124 ++ api/basic_json/flatten.md | 50 + api/basic_json/flatten/index.html | 2 +- api/basic_json/flatten/index.md | 89 ++ api/basic_json/format_as.md | 95 ++ api/basic_json/format_as/index.html | 2 +- api/basic_json/format_as/index.md | 154 +++ api/basic_json/from_bjdata.md | 103 ++ api/basic_json/from_bjdata/index.html | 2 +- api/basic_json/from_bjdata/index.md | 116 ++ api/basic_json/from_bson.md | 115 ++ api/basic_json/from_bson/index.html | 2 +- api/basic_json/from_bson/index.md | 124 ++ api/basic_json/from_cbor.md | 125 ++ api/basic_json/from_cbor/index.html | 2 +- api/basic_json/from_cbor/index.md | 131 ++ api/basic_json/from_msgpack.md | 117 ++ api/basic_json/from_msgpack/index.html | 2 +- api/basic_json/from_msgpack/index.md | 125 ++ api/basic_json/from_ubjson.md | 116 ++ api/basic_json/from_ubjson/index.html | 2 +- api/basic_json/from_ubjson/index.md | 124 ++ api/basic_json/front.md | 58 + api/basic_json/front/index.html | 2 +- api/basic_json/front/index.md | 88 ++ api/basic_json/get.md | 164 +++ api/basic_json/get/index.html | 2 +- api/basic_json/get/index.md | 219 +++ api/basic_json/get_allocator.md | 31 + api/basic_json/get_allocator/index.html | 2 +- api/basic_json/get_allocator/index.md | 48 + api/basic_json/get_binary.md | 50 + api/basic_json/get_binary/index.html | 2 +- api/basic_json/get_binary/index.md | 65 + api/basic_json/get_ptr.md | 94 ++ api/basic_json/get_ptr/index.html | 2 +- api/basic_json/get_ptr/index.md | 107 ++ api/basic_json/get_ref.md | 68 + api/basic_json/get_ref/index.html | 2 +- api/basic_json/get_ref/index.md | 89 ++ api/basic_json/get_to.md | 69 + api/basic_json/get_to/index.html | 2 +- api/basic_json/get_to/index.md | 133 ++ api/basic_json/index.html | 2 +- api/basic_json/index.md | 383 ++++++ api/basic_json/input_format_t.md | 52 + api/basic_json/input_format_t/index.html | 2 +- api/basic_json/input_format_t/index.md | 161 +++ api/basic_json/insert.md | 197 +++ api/basic_json/insert/index.html | 2 +- api/basic_json/insert/index.md | 266 ++++ api/basic_json/invalid_iterator.md | 78 ++ api/basic_json/invalid_iterator/index.html | 2 +- api/basic_json/invalid_iterator/index.md | 99 ++ api/basic_json/is_array.md | 39 + api/basic_json/is_array/index.html | 2 +- api/basic_json/is_array/index.md | 76 ++ api/basic_json/is_binary.md | 39 + api/basic_json/is_binary/index.html | 2 +- api/basic_json/is_binary/index.md | 76 ++ api/basic_json/is_boolean.md | 39 + api/basic_json/is_boolean/index.html | 2 +- api/basic_json/is_boolean/index.md | 76 ++ api/basic_json/is_discarded.md | 74 + api/basic_json/is_discarded/index.html | 2 +- api/basic_json/is_discarded/index.md | 103 ++ api/basic_json/is_null.md | 39 + api/basic_json/is_null/index.html | 2 +- api/basic_json/is_null/index.md | 76 ++ api/basic_json/is_number.md | 56 + api/basic_json/is_number/index.html | 2 +- api/basic_json/is_number/index.md | 92 ++ api/basic_json/is_number_float.md | 46 + api/basic_json/is_number_float/index.html | 2 +- api/basic_json/is_number_float/index.md | 82 ++ api/basic_json/is_number_integer.md | 47 + api/basic_json/is_number_integer/index.html | 2 +- api/basic_json/is_number_integer/index.md | 83 ++ api/basic_json/is_number_unsigned.md | 46 + api/basic_json/is_number_unsigned/index.html | 2 +- api/basic_json/is_number_unsigned/index.md | 82 ++ api/basic_json/is_object.md | 39 + api/basic_json/is_object/index.html | 2 +- api/basic_json/is_object/index.md | 76 ++ api/basic_json/is_primitive.md | 69 + api/basic_json/is_primitive/index.html | 2 +- api/basic_json/is_primitive/index.md | 103 ++ api/basic_json/is_string.md | 39 + api/basic_json/is_string/index.html | 2 +- api/basic_json/is_string/index.md | 76 ++ api/basic_json/is_structured.md | 63 + api/basic_json/is_structured/index.html | 2 +- api/basic_json/is_structured/index.md | 99 ++ api/basic_json/items.md | 105 ++ api/basic_json/items/index.html | 2 +- api/basic_json/items/index.md | 126 ++ api/basic_json/json_base_class_t.md | 45 + api/basic_json/json_base_class_t/index.html | 2 +- api/basic_json/json_base_class_t/index.md | 131 ++ api/basic_json/json_serializer.md | 41 + api/basic_json/json_serializer/index.html | 2 +- api/basic_json/json_serializer/index.md | 90 ++ api/basic_json/max_size.md | 60 + api/basic_json/max_size/index.html | 2 +- api/basic_json/max_size/index.md | 86 ++ api/basic_json/merge_patch.md | 63 + api/basic_json/merge_patch/index.html | 2 +- api/basic_json/merge_patch/index.md | 110 ++ api/basic_json/meta.md | 56 + api/basic_json/meta/index.html | 2 +- api/basic_json/meta/index.md | 81 ++ api/basic_json/number_float_t.md | 70 + api/basic_json/number_float_t/index.html | 2 +- api/basic_json/number_float_t/index.md | 67 + api/basic_json/number_integer_t.md | 75 ++ api/basic_json/number_integer_t/index.html | 2 +- api/basic_json/number_integer_t/index.md | 72 + api/basic_json/number_unsigned_t.md | 75 ++ api/basic_json/number_unsigned_t/index.html | 2 +- api/basic_json/number_unsigned_t/index.md | 72 + api/basic_json/object.md | 64 + api/basic_json/object/index.html | 2 +- api/basic_json/object/index.md | 87 ++ api/basic_json/object_comparator_t.md | 32 + api/basic_json/object_comparator_t/index.html | 2 +- api/basic_json/object_comparator_t/index.md | 41 + api/basic_json/object_t.md | 114 ++ api/basic_json/object_t/index.html | 2 +- api/basic_json/object_t/index.md | 104 ++ api/basic_json/operator%2B%3D.md | 127 ++ api/basic_json/operator%3D.md | 53 + api/basic_json/operator%5B%5D.md | 255 ++++ api/basic_json/operator+=/index.html | 2 +- api/basic_json/operator+=/index.md | 195 +++ api/basic_json/operator=/index.html | 2 +- api/basic_json/operator=/index.md | 68 + api/basic_json/operator[]/index.html | 2 +- api/basic_json/operator[]/index.md | 480 +++++++ api/basic_json/operator_ValueType.md | 87 ++ api/basic_json/operator_ValueType/index.html | 2 +- api/basic_json/operator_ValueType/index.md | 146 ++ api/basic_json/operator_eq.md | 173 +++ api/basic_json/operator_eq/index.html | 2 +- api/basic_json/operator_eq/index.md | 231 ++++ api/basic_json/operator_ge.md | 86 ++ api/basic_json/operator_ge/index.html | 2 +- api/basic_json/operator_ge/index.md | 106 ++ api/basic_json/operator_gt.md | 86 ++ api/basic_json/operator_gt/index.html | 2 +- api/basic_json/operator_gt/index.md | 106 ++ api/basic_json/operator_le.md | 87 ++ api/basic_json/operator_le/index.html | 2 +- api/basic_json/operator_le/index.md | 106 ++ api/basic_json/operator_lt.md | 96 ++ api/basic_json/operator_lt/index.html | 2 +- api/basic_json/operator_lt/index.md | 115 ++ api/basic_json/operator_ne.md | 98 ++ api/basic_json/operator_ne/index.html | 2 +- api/basic_json/operator_ne/index.md | 145 ++ api/basic_json/operator_spaceship.md | 100 ++ api/basic_json/operator_spaceship/index.html | 2 +- api/basic_json/operator_spaceship/index.md | 177 +++ api/basic_json/operator_value_t.md | 54 + api/basic_json/operator_value_t/index.html | 2 +- api/basic_json/operator_value_t/index.md | 98 ++ api/basic_json/other_error.md | 78 ++ api/basic_json/other_error/index.html | 2 +- api/basic_json/other_error/index.md | 108 ++ api/basic_json/out_of_range.md | 79 ++ api/basic_json/out_of_range/index.html | 2 +- api/basic_json/out_of_range/index.md | 98 ++ api/basic_json/parse.md | 247 ++++ api/basic_json/parse/index.html | 2 +- api/basic_json/parse/index.md | 624 +++++++++ api/basic_json/parse_error.md | 87 ++ api/basic_json/parse_error/index.html | 2 +- api/basic_json/parse_error/index.md | 106 ++ api/basic_json/parse_event_t.md | 34 + api/basic_json/parse_event_t/index.html | 2 +- api/basic_json/parse_event_t/index.md | 32 + api/basic_json/parser_callback_t.md | 78 ++ api/basic_json/parser_callback_t/index.html | 2 +- api/basic_json/parser_callback_t/index.md | 142 ++ api/basic_json/patch.md | 77 ++ api/basic_json/patch/index.html | 2 +- api/basic_json/patch/index.md | 107 ++ api/basic_json/patch_inplace.md | 74 + api/basic_json/patch_inplace/index.html | 2 +- api/basic_json/patch_inplace/index.md | 107 ++ api/basic_json/push_back.md | 124 ++ api/basic_json/push_back/index.html | 2 +- api/basic_json/push_back/index.md | 192 +++ api/basic_json/rbegin.md | 42 + api/basic_json/rbegin/index.html | 2 +- api/basic_json/rbegin/index.md | 55 + api/basic_json/rend.md | 43 + api/basic_json/rend/index.html | 2 +- api/basic_json/rend/index.md | 58 + api/basic_json/sax_parse.md | 135 ++ api/basic_json/sax_parse/index.html | 2 +- api/basic_json/sax_parse/index.md | 283 ++++ api/basic_json/size.md | 57 + api/basic_json/size/index.html | 2 +- api/basic_json/size/index.md | 90 ++ api/basic_json/start_pos.md | 68 + api/basic_json/start_pos/index.html | 2 +- api/basic_json/start_pos/index.md | 163 +++ api/basic_json/std_formatter.md | 57 + api/basic_json/std_formatter/index.html | 2 +- api/basic_json/std_formatter/index.md | 82 ++ api/basic_json/std_hash.md | 34 + api/basic_json/std_hash/index.html | 2 +- api/basic_json/std_hash/index.md | 57 + api/basic_json/std_swap.md | 59 + api/basic_json/std_swap/index.html | 2 +- api/basic_json/std_swap/index.md | 76 ++ api/basic_json/string_t.md | 66 + api/basic_json/string_t/index.html | 2 +- api/basic_json/string_t/index.md | 68 + api/basic_json/swap.md | 169 +++ api/basic_json/swap/index.html | 2 +- api/basic_json/swap/index.md | 250 ++++ api/basic_json/to_bjdata.md | 86 ++ api/basic_json/to_bjdata/index.html | 2 +- api/basic_json/to_bjdata/index.md | 144 ++ api/basic_json/to_bson.md | 74 + api/basic_json/to_bson/index.html | 2 +- api/basic_json/to_bson/index.md | 90 ++ api/basic_json/to_cbor.md | 69 + api/basic_json/to_cbor/index.html | 2 +- api/basic_json/to_cbor/index.md | 86 ++ api/basic_json/to_msgpack.md | 67 + api/basic_json/to_msgpack/index.html | 2 +- api/basic_json/to_msgpack/index.md | 85 ++ api/basic_json/to_string.md | 66 + api/basic_json/to_string/index.html | 2 +- api/basic_json/to_string/index.md | 84 ++ api/basic_json/to_ubjson.md | 78 ++ api/basic_json/to_ubjson/index.html | 2 +- api/basic_json/to_ubjson/index.md | 138 ++ api/basic_json/type.md | 54 + api/basic_json/type/index.html | 2 +- api/basic_json/type/index.md | 88 ++ api/basic_json/type_error.md | 79 ++ api/basic_json/type_error/index.html | 2 +- api/basic_json/type_error/index.md | 98 ++ api/basic_json/type_name.md | 54 + api/basic_json/type_name/index.html | 2 +- api/basic_json/type_name/index.md | 86 ++ api/basic_json/unflatten.md | 65 + api/basic_json/unflatten/index.html | 2 +- api/basic_json/unflatten/index.md | 102 ++ api/basic_json/update.md | 157 +++ api/basic_json/update/index.html | 2 +- api/basic_json/update/index.md | 223 +++ api/basic_json/value.md | 187 +++ api/basic_json/value/index.html | 2 +- api/basic_json/value/index.md | 270 ++++ api/basic_json/value_t.md | 81 ++ api/basic_json/value_t/index.html | 2 +- api/basic_json/value_t/index.md | 105 ++ api/basic_json/~basic_json.md | 21 + api/basic_json/~basic_json/index.html | 2 +- api/basic_json/~basic_json/index.md | 19 + api/byte_container_with_subtype.md | 35 + .../byte_container_with_subtype.md | 46 + .../byte_container_with_subtype/index.html | 2 +- .../byte_container_with_subtype/index.md | 68 + .../clear_subtype.md | 36 + .../clear_subtype/index.html | 2 +- .../clear_subtype/index.md | 56 + .../has_subtype.md | 39 + .../has_subtype/index.html | 2 +- .../has_subtype/index.md | 58 + api/byte_container_with_subtype/index.html | 2 +- api/byte_container_with_subtype/index.md | 32 + .../set_subtype.md | 41 + .../set_subtype/index.html | 2 +- .../set_subtype/index.md | 61 + api/byte_container_with_subtype/subtype.md | 42 + .../subtype/index.html | 2 +- .../subtype/index.md | 62 + api/json.md | 28 + api/json/index.html | 2 +- api/json/index.md | 91 ++ api/json_pointer.md | 55 + api/json_pointer/back.md | 40 + api/json_pointer/back/index.html | 2 +- api/json_pointer/back/index.md | 55 + api/json_pointer/empty.md | 39 + api/json_pointer/empty/index.html | 2 +- api/json_pointer/empty/index.md | 61 + api/json_pointer/front.md | 39 + api/json_pointer/front/index.html | 2 +- api/json_pointer/front/index.md | 54 + api/json_pointer/index.html | 2 +- api/json_pointer/index.md | 51 + api/json_pointer/json_pointer.md | 41 + api/json_pointer/json_pointer/index.html | 2 +- api/json_pointer/json_pointer/index.md | 85 ++ api/json_pointer/operator_eq.md | 113 ++ api/json_pointer/operator_eq/index.html | 2 +- api/json_pointer/operator_eq/index.md | 160 +++ api/json_pointer/operator_ne.md | 109 ++ api/json_pointer/operator_ne/index.html | 2 +- api/json_pointer/operator_ne/index.md | 154 +++ api/json_pointer/operator_slash.md | 64 + api/json_pointer/operator_slash/index.html | 2 +- api/json_pointer/operator_slash/index.md | 80 ++ api/json_pointer/operator_slasheq.md | 61 + api/json_pointer/operator_slasheq/index.html | 2 +- api/json_pointer/operator_slasheq/index.md | 83 ++ api/json_pointer/operator_string_t.md | 52 + api/json_pointer/operator_string_t/index.html | 2 +- api/json_pointer/operator_string_t/index.md | 70 + api/json_pointer/parent_pointer.md | 44 + api/json_pointer/parent_pointer/index.html | 2 +- api/json_pointer/parent_pointer/index.md | 63 + api/json_pointer/pop_back.md | 35 + api/json_pointer/pop_back/index.html | 2 +- api/json_pointer/pop_back/index.md | 58 + api/json_pointer/pop_front.md | 35 + api/json_pointer/pop_front/index.html | 2 +- api/json_pointer/pop_front/index.md | 58 + api/json_pointer/push_back.md | 39 + api/json_pointer/push_back/index.html | 2 +- api/json_pointer/push_back/index.md | 61 + api/json_pointer/push_front.md | 38 + api/json_pointer/push_front/index.html | 2 +- api/json_pointer/push_front/index.md | 60 + api/json_pointer/string_t.md | 28 + api/json_pointer/string_t/index.html | 2 +- api/json_pointer/string_t/index.md | 42 + api/json_pointer/to_string.md | 40 + api/json_pointer/to_string/index.html | 2 +- api/json_pointer/to_string/index.md | 84 ++ api/json_sax.md | 44 + api/json_sax/binary.md | 40 + api/json_sax/binary/index.html | 2 +- api/json_sax/binary/index.md | 154 +++ api/json_sax/boolean.md | 36 + api/json_sax/boolean/index.html | 2 +- api/json_sax/boolean/index.md | 201 +++ api/json_sax/end_array.md | 31 + api/json_sax/end_array/index.html | 2 +- api/json_sax/end_array/index.md | 197 +++ api/json_sax/end_object.md | 31 + api/json_sax/end_object/index.html | 2 +- api/json_sax/end_object/index.md | 197 +++ api/json_sax/index.html | 2 +- api/json_sax/index.md | 41 + api/json_sax/key.md | 40 + api/json_sax/key/index.html | 2 +- api/json_sax/key/index.md | 205 +++ api/json_sax/null.md | 31 + api/json_sax/null/index.html | 2 +- api/json_sax/null/index.md | 197 +++ api/json_sax/number_float.md | 39 + api/json_sax/number_float/index.html | 2 +- api/json_sax/number_float/index.md | 203 +++ api/json_sax/number_integer.md | 36 + api/json_sax/number_integer/index.html | 2 +- api/json_sax/number_integer/index.md | 201 +++ api/json_sax/number_unsigned.md | 36 + api/json_sax/number_unsigned/index.html | 2 +- api/json_sax/number_unsigned/index.md | 201 +++ api/json_sax/parse_error.md | 44 + api/json_sax/parse_error/index.html | 2 +- api/json_sax/parse_error/index.md | 207 +++ api/json_sax/start_array.md | 40 + api/json_sax/start_array/index.html | 2 +- api/json_sax/start_array/index.md | 205 +++ api/json_sax/start_object.md | 40 + api/json_sax/start_object/index.html | 2 +- api/json_sax/start_object/index.md | 205 +++ api/json_sax/string.md | 40 + api/json_sax/string/index.html | 2 +- api/json_sax/string/index.md | 205 +++ api/macros.md | 111 ++ api/macros/index.html | 2 +- api/macros/index.md | 90 ++ api/macros/json_assert.md | 88 ++ api/macros/json_assert/index.html | 2 +- api/macros/json_assert/index.md | 85 ++ api/macros/json_brace_init_copy_semantics.md | 95 ++ .../json_brace_init_copy_semantics/index.html | 2 +- .../json_brace_init_copy_semantics/index.md | 90 ++ api/macros/json_diagnostic_positions.md | 119 ++ .../json_diagnostic_positions/index.html | 2 +- api/macros/json_diagnostic_positions/index.md | 262 ++++ api/macros/json_diagnostics.md | 94 ++ api/macros/json_diagnostics/index.html | 2 +- api/macros/json_diagnostics/index.md | 156 +++ api/macros/json_disable_enum_serialization.md | 153 +++ .../index.html | 2 +- .../json_disable_enum_serialization/index.md | 145 ++ api/macros/json_has_cpp_11.md | 47 + api/macros/json_has_cpp_11/index.html | 2 +- api/macros/json_has_cpp_11/index.md | 40 + api/macros/json_has_filesystem.md | 43 + api/macros/json_has_filesystem/index.html | 2 +- api/macros/json_has_filesystem/index.md | 34 + api/macros/json_has_ranges.md | 31 + api/macros/json_has_ranges/index.html | 2 +- api/macros/json_has_ranges/index.md | 30 + api/macros/json_has_static_rtti.md | 31 + api/macros/json_has_static_rtti/index.html | 2 +- api/macros/json_has_static_rtti/index.md | 30 + api/macros/json_has_std_format.md | 41 + api/macros/json_has_std_format/index.html | 2 +- api/macros/json_has_std_format/index.md | 36 + api/macros/json_has_three_way_comparison.md | 32 + .../json_has_three_way_comparison/index.html | 2 +- .../json_has_three_way_comparison/index.md | 30 + api/macros/json_no_io.md | 35 + api/macros/json_no_io/index.html | 2 +- api/macros/json_no_io/index.md | 32 + api/macros/json_noexception.md | 45 + api/macros/json_noexception/index.html | 2 +- api/macros/json_noexception/index.md | 42 + api/macros/json_skip_library_version_check.md | 48 + .../index.html | 2 +- .../json_skip_library_version_check/index.md | 46 + .../json_skip_unsupported_compiler_check.md | 33 + .../index.html | 2 +- .../index.md | 32 + api/macros/json_throw_user.md | 75 ++ api/macros/json_throw_user/index.html | 2 +- api/macros/json_throw_user/index.md | 67 + api/macros/json_use_global_udls.md | 99 ++ api/macros/json_use_global_udls/index.html | 2 +- api/macros/json_use_global_udls/index.md | 94 ++ api/macros/json_use_implicit_conversions.md | 60 + .../json_use_implicit_conversions/index.html | 2 +- .../json_use_implicit_conversions/index.md | 55 + ...n_use_legacy_discarded_value_comparison.md | 81 ++ .../index.html | 2 +- .../index.md | 74 + api/macros/nlohmann_define_derived_type.md | 177 +++ .../nlohmann_define_derived_type/index.html | 2 +- .../nlohmann_define_derived_type/index.md | 196 +++ api/macros/nlohmann_define_type_intrusive.md | 170 +++ .../nlohmann_define_type_intrusive/index.html | 2 +- .../nlohmann_define_type_intrusive/index.md | 424 ++++++ .../nlohmann_define_type_non_intrusive.md | 171 +++ .../index.html | 2 +- .../index.md | 393 ++++++ api/macros/nlohmann_define_type_with_names.md | 78 ++ .../index.html | 2 +- .../nlohmann_define_type_with_names/index.md | 160 +++ api/macros/nlohmann_json_namespace.md | 41 + api/macros/nlohmann_json_namespace/index.html | 2 +- api/macros/nlohmann_json_namespace/index.md | 51 + api/macros/nlohmann_json_namespace_begin.md | 61 + .../nlohmann_json_namespace_begin/index.html | 2 +- .../nlohmann_json_namespace_begin/index.md | 91 ++ .../nlohmann_json_namespace_no_version.md | 45 + .../index.html | 2 +- .../index.md | 55 + api/macros/nlohmann_json_serialize_enum.md | 86 ++ .../nlohmann_json_serialize_enum/index.html | 2 +- .../nlohmann_json_serialize_enum/index.md | 171 +++ .../nlohmann_json_serialize_enum_strict.md | 105 ++ .../index.html | 2 +- .../index.md | 230 ++++ api/macros/nlohmann_json_version_major.md | 40 + .../nlohmann_json_version_major/index.html | 2 +- .../nlohmann_json_version_major/index.md | 49 + api/operator_gtgt.md | 65 + api/operator_gtgt/index.html | 2 +- api/operator_gtgt/index.md | 97 ++ api/operator_literal_json.md | 67 + api/operator_literal_json/index.html | 2 +- api/operator_literal_json/index.md | 79 ++ api/operator_literal_json_pointer.md | 66 + api/operator_literal_json_pointer/index.html | 2 +- api/operator_literal_json_pointer/index.md | 77 ++ api/operator_ltlt.md | 93 ++ api/operator_ltlt/index.html | 2 +- api/operator_ltlt/index.md | 131 ++ api/ordered_json.md | 39 + api/ordered_json/index.html | 2 +- api/ordered_json/index.md | 53 + api/ordered_map.md | 82 ++ api/ordered_map/index.html | 2 +- api/ordered_map/index.md | 129 ++ .../badge/vertical-allrepos/nlohmann-json.svg | 2 +- community.md | 7 + community/code_of_conduct.md | 1 + community/code_of_conduct/index.html | 2 +- community/code_of_conduct/index.md | 77 ++ community/contribution_guidelines.md | 1 + community/contribution_guidelines/index.html | 2 +- community/contribution_guidelines/index.md | 160 +++ community/governance.md | 122 ++ community/governance/index.html | 2 +- community/governance/index.md | 74 + community/index.html | 2 +- community/index.md | 7 + community/quality_assurance.md | 227 ++++ community/quality_assurance/index.html | 2 +- community/quality_assurance/index.md | 766 +++++++++++ community/security_policy.md | 1 + community/security_policy/index.html | 2 +- community/security_policy/index.md | 18 + features.md | 53 + features/arbitrary_types.md | 327 +++++ features/arbitrary_types/index.html | 2 +- features/arbitrary_types/index.md | 322 +++++ features/assertions.md | 144 ++ features/assertions/index.html | 2 +- features/assertions/index.md | 132 ++ features/binary_formats.md | 52 + features/binary_formats/bjdata.md | 206 +++ features/binary_formats/bjdata/index.html | 2 +- features/binary_formats/bjdata/index.md | 254 ++++ features/binary_formats/bson.md | 98 ++ features/binary_formats/bson/index.html | 2 +- features/binary_formats/bson/index.md | 136 ++ features/binary_formats/cbor.md | 181 +++ features/binary_formats/cbor/index.html | 2 +- features/binary_formats/cbor/index.md | 221 +++ features/binary_formats/index.html | 2 +- features/binary_formats/index.md | 51 + features/binary_formats/messagepack.md | 143 ++ .../binary_formats/messagepack/index.html | 2 +- features/binary_formats/messagepack/index.md | 181 +++ features/binary_formats/ubjson.md | 126 ++ features/binary_formats/ubjson/index.html | 2 +- features/binary_formats/ubjson/index.md | 206 +++ features/binary_values.md | 374 ++++++ features/binary_values/index.html | 2 +- features/binary_values/index.md | 353 +++++ features/comments.md | 40 + features/comments/index.html | 2 +- features/comments/index.md | 81 ++ features/conversions.md | 91 ++ features/conversions/index.html | 2 +- features/conversions/index.md | 144 ++ features/creating_values.md | 103 ++ features/creating_values/index.html | 2 +- features/creating_values/index.md | 107 ++ features/element_access.md | 9 + features/element_access/checked_access.md | 91 ++ .../element_access/checked_access/index.html | 2 +- .../element_access/checked_access/index.md | 82 ++ features/element_access/default_value.md | 64 + .../element_access/default_value/index.html | 2 +- .../element_access/default_value/index.md | 72 + features/element_access/index.html | 2 +- features/element_access/index.md | 9 + features/element_access/unchecked_access.md | 112 ++ .../unchecked_access/index.html | 2 +- .../element_access/unchecked_access/index.md | 102 ++ features/enum_conversion.md | 62 + features/enum_conversion/index.html | 2 +- features/enum_conversion/index.md | 54 + features/index.html | 2 +- features/index.md | 39 + features/iterators.md | 155 +++ features/iterators/index.html | 2 +- features/iterators/index.md | 151 +++ features/json_patch.md | 47 + features/json_patch/index.html | 2 +- features/json_patch/index.md | 147 ++ features/json_pointer.md | 126 ++ features/json_pointer/index.html | 2 +- features/json_pointer/index.md | 120 ++ features/macros.md | 174 +++ features/macros/index.html | 2 +- features/macros/index.md | 139 ++ features/merge_patch.md | 20 + features/merge_patch/index.html | 2 +- features/merge_patch/index.md | 69 + features/modifying_values.md | 77 ++ features/modifying_values/index.html | 2 +- features/modifying_values/index.md | 106 ++ features/modules.md | 40 + features/modules/index.html | 2 +- features/modules/index.md | 45 + features/namespace.md | 95 ++ features/namespace/index.html | 2 +- features/namespace/index.md | 73 + features/object_order.md | 109 ++ features/object_order/index.html | 2 +- features/object_order/index.md | 123 ++ features/parsing.md | 61 + features/parsing/index.html | 2 +- features/parsing/index.md | 49 + features/parsing/json_lines.md | 49 + features/parsing/json_lines/index.html | 2 +- features/parsing/json_lines/index.md | 71 + features/parsing/parse_exceptions.md | 121 ++ features/parsing/parse_exceptions/index.html | 2 +- features/parsing/parse_exceptions/index.md | 112 ++ features/parsing/parser_callbacks.md | 83 ++ features/parsing/parser_callbacks/index.html | 2 +- features/parsing/parser_callbacks/index.md | 155 +++ features/parsing/sax_interface.md | 76 ++ features/parsing/sax_interface/index.html | 2 +- features/parsing/sax_interface/index.md | 76 ++ features/serialization.md | 129 ++ features/serialization/index.html | 2 +- features/serialization/index.md | 230 ++++ features/trailing_commas.md | 39 + features/trailing_commas/index.html | 2 +- features/trailing_commas/index.md | 86 ++ features/types.md | 271 ++++ features/types/index.html | 2 +- features/types/index.md | 265 ++++ features/types/number_handling.md | 341 +++++ features/types/number_handling/index.html | 2 +- features/types/number_handling/index.md | 282 ++++ home/architecture.md | 124 ++ home/architecture/index.html | 2 +- home/architecture/index.md | 123 ++ home/customers.md | 178 +++ home/customers/index.html | 2 +- home/customers/index.md | 175 +++ home/design_goals.md | 17 + home/design_goals/index.html | 2 +- home/design_goals/index.md | 14 + home/exceptions.md | 929 +++++++++++++ home/exceptions/index.html | 2 +- home/exceptions/index.md | 1090 +++++++++++++++ home/faq.md | 225 ++++ home/faq/index.html | 2 +- home/faq/index.md | 207 +++ home/license.md | 21 + home/license/index.html | 2 +- home/license/index.md | 19 + home/releases.md | 439 ++++++ home/releases/index.html | 2 +- home/releases/index.md | 329 +++++ home/sponsors.md | 19 + home/sponsors/index.html | 2 +- home/sponsors/index.md | 19 + index.html | 2 +- index.md | 1 + integration.md | 18 + integration/cmake.md | 183 +++ integration/cmake/index.html | 2 +- integration/cmake/index.md | 177 +++ integration/index.html | 2 +- integration/index.md | 14 + integration/migration_guide.md | 260 ++++ integration/migration_guide/index.html | 2 +- integration/migration_guide/index.md | 179 +++ integration/package_managers.md | 937 +++++++++++++ integration/package_managers/index.html | 2 +- integration/package_managers/index.md | 1196 +++++++++++++++++ integration/pkg-config.md | 13 + integration/pkg-config/index.html | 2 +- integration/pkg-config/index.md | 13 + llms.txt | 271 ++++ robots.txt | 4 + sitemap.xml | 502 +++---- sitemap.xml.gz | Bin 1825 -> 1825 bytes 758 files changed, 56489 insertions(+), 503 deletions(-) create mode 100644 ..md create mode 100644 api/adl_serializer.md create mode 100644 api/adl_serializer/from_json.md create mode 100644 api/adl_serializer/from_json/index.md create mode 100644 api/adl_serializer/index.md create mode 100644 api/adl_serializer/to_json.md create mode 100644 api/adl_serializer/to_json/index.md create mode 100644 api/basic_json.md create mode 100644 api/basic_json/accept.md create mode 100644 api/basic_json/accept/index.md create mode 100644 api/basic_json/array.md create mode 100644 api/basic_json/array/index.md create mode 100644 api/basic_json/array_t.md create mode 100644 api/basic_json/array_t/index.md create mode 100644 api/basic_json/at.md create mode 100644 api/basic_json/at/index.md create mode 100644 api/basic_json/back.md create mode 100644 api/basic_json/back/index.md create mode 100644 api/basic_json/basic_json.md create mode 100644 api/basic_json/basic_json/index.md create mode 100644 api/basic_json/begin.md create mode 100644 api/basic_json/begin/index.md create mode 100644 api/basic_json/binary.md create mode 100644 api/basic_json/binary/index.md create mode 100644 api/basic_json/binary_t.md create mode 100644 api/basic_json/binary_t/index.md create mode 100644 api/basic_json/boolean_t.md create mode 100644 api/basic_json/boolean_t/index.md create mode 100644 api/basic_json/cbegin.md create mode 100644 api/basic_json/cbegin/index.md create mode 100644 api/basic_json/cbor_tag_handler_t.md create mode 100644 api/basic_json/cbor_tag_handler_t/index.md create mode 100644 api/basic_json/cend.md create mode 100644 api/basic_json/cend/index.md create mode 100644 api/basic_json/clear.md create mode 100644 api/basic_json/clear/index.md create mode 100644 api/basic_json/contains.md create mode 100644 api/basic_json/contains/index.md create mode 100644 api/basic_json/count.md create mode 100644 api/basic_json/count/index.md create mode 100644 api/basic_json/crbegin.md create mode 100644 api/basic_json/crbegin/index.md create mode 100644 api/basic_json/crend.md create mode 100644 api/basic_json/crend/index.md create mode 100644 api/basic_json/default_object_comparator_t.md create mode 100644 api/basic_json/default_object_comparator_t/index.md create mode 100644 api/basic_json/diff.md create mode 100644 api/basic_json/diff/index.md create mode 100644 api/basic_json/dump.md create mode 100644 api/basic_json/dump/index.md create mode 100644 api/basic_json/emplace.md create mode 100644 api/basic_json/emplace/index.md create mode 100644 api/basic_json/emplace_back.md create mode 100644 api/basic_json/emplace_back/index.md create mode 100644 api/basic_json/empty.md create mode 100644 api/basic_json/empty/index.md create mode 100644 api/basic_json/end.md create mode 100644 api/basic_json/end/index.md create mode 100644 api/basic_json/end_pos.md create mode 100644 api/basic_json/end_pos/index.md create mode 100644 api/basic_json/erase.md create mode 100644 api/basic_json/erase/index.md create mode 100644 api/basic_json/error_handler_t.md create mode 100644 api/basic_json/error_handler_t/index.md create mode 100644 api/basic_json/exception.md create mode 100644 api/basic_json/exception/index.md create mode 100644 api/basic_json/find.md create mode 100644 api/basic_json/find/index.md create mode 100644 api/basic_json/flatten.md create mode 100644 api/basic_json/flatten/index.md create mode 100644 api/basic_json/format_as.md create mode 100644 api/basic_json/format_as/index.md create mode 100644 api/basic_json/from_bjdata.md create mode 100644 api/basic_json/from_bjdata/index.md create mode 100644 api/basic_json/from_bson.md create mode 100644 api/basic_json/from_bson/index.md create mode 100644 api/basic_json/from_cbor.md create mode 100644 api/basic_json/from_cbor/index.md create mode 100644 api/basic_json/from_msgpack.md create mode 100644 api/basic_json/from_msgpack/index.md create mode 100644 api/basic_json/from_ubjson.md create mode 100644 api/basic_json/from_ubjson/index.md create mode 100644 api/basic_json/front.md create mode 100644 api/basic_json/front/index.md create mode 100644 api/basic_json/get.md create mode 100644 api/basic_json/get/index.md create mode 100644 api/basic_json/get_allocator.md create mode 100644 api/basic_json/get_allocator/index.md create mode 100644 api/basic_json/get_binary.md create mode 100644 api/basic_json/get_binary/index.md create mode 100644 api/basic_json/get_ptr.md create mode 100644 api/basic_json/get_ptr/index.md create mode 100644 api/basic_json/get_ref.md create mode 100644 api/basic_json/get_ref/index.md create mode 100644 api/basic_json/get_to.md create mode 100644 api/basic_json/get_to/index.md create mode 100644 api/basic_json/index.md create mode 100644 api/basic_json/input_format_t.md create mode 100644 api/basic_json/input_format_t/index.md create mode 100644 api/basic_json/insert.md create mode 100644 api/basic_json/insert/index.md create mode 100644 api/basic_json/invalid_iterator.md create mode 100644 api/basic_json/invalid_iterator/index.md create mode 100644 api/basic_json/is_array.md create mode 100644 api/basic_json/is_array/index.md create mode 100644 api/basic_json/is_binary.md create mode 100644 api/basic_json/is_binary/index.md create mode 100644 api/basic_json/is_boolean.md create mode 100644 api/basic_json/is_boolean/index.md create mode 100644 api/basic_json/is_discarded.md create mode 100644 api/basic_json/is_discarded/index.md create mode 100644 api/basic_json/is_null.md create mode 100644 api/basic_json/is_null/index.md create mode 100644 api/basic_json/is_number.md create mode 100644 api/basic_json/is_number/index.md create mode 100644 api/basic_json/is_number_float.md create mode 100644 api/basic_json/is_number_float/index.md create mode 100644 api/basic_json/is_number_integer.md create mode 100644 api/basic_json/is_number_integer/index.md create mode 100644 api/basic_json/is_number_unsigned.md create mode 100644 api/basic_json/is_number_unsigned/index.md create mode 100644 api/basic_json/is_object.md create mode 100644 api/basic_json/is_object/index.md create mode 100644 api/basic_json/is_primitive.md create mode 100644 api/basic_json/is_primitive/index.md create mode 100644 api/basic_json/is_string.md create mode 100644 api/basic_json/is_string/index.md create mode 100644 api/basic_json/is_structured.md create mode 100644 api/basic_json/is_structured/index.md create mode 100644 api/basic_json/items.md create mode 100644 api/basic_json/items/index.md create mode 100644 api/basic_json/json_base_class_t.md create mode 100644 api/basic_json/json_base_class_t/index.md create mode 100644 api/basic_json/json_serializer.md create mode 100644 api/basic_json/json_serializer/index.md create mode 100644 api/basic_json/max_size.md create mode 100644 api/basic_json/max_size/index.md create mode 100644 api/basic_json/merge_patch.md create mode 100644 api/basic_json/merge_patch/index.md create mode 100644 api/basic_json/meta.md create mode 100644 api/basic_json/meta/index.md create mode 100644 api/basic_json/number_float_t.md create mode 100644 api/basic_json/number_float_t/index.md create mode 100644 api/basic_json/number_integer_t.md create mode 100644 api/basic_json/number_integer_t/index.md create mode 100644 api/basic_json/number_unsigned_t.md create mode 100644 api/basic_json/number_unsigned_t/index.md create mode 100644 api/basic_json/object.md create mode 100644 api/basic_json/object/index.md create mode 100644 api/basic_json/object_comparator_t.md create mode 100644 api/basic_json/object_comparator_t/index.md create mode 100644 api/basic_json/object_t.md create mode 100644 api/basic_json/object_t/index.md create mode 100644 api/basic_json/operator%2B%3D.md create mode 100644 api/basic_json/operator%3D.md create mode 100644 api/basic_json/operator%5B%5D.md create mode 100644 api/basic_json/operator+=/index.md create mode 100644 api/basic_json/operator=/index.md create mode 100644 api/basic_json/operator[]/index.md create mode 100644 api/basic_json/operator_ValueType.md create mode 100644 api/basic_json/operator_ValueType/index.md create mode 100644 api/basic_json/operator_eq.md create mode 100644 api/basic_json/operator_eq/index.md create mode 100644 api/basic_json/operator_ge.md create mode 100644 api/basic_json/operator_ge/index.md create mode 100644 api/basic_json/operator_gt.md create mode 100644 api/basic_json/operator_gt/index.md create mode 100644 api/basic_json/operator_le.md create mode 100644 api/basic_json/operator_le/index.md create mode 100644 api/basic_json/operator_lt.md create mode 100644 api/basic_json/operator_lt/index.md create mode 100644 api/basic_json/operator_ne.md create mode 100644 api/basic_json/operator_ne/index.md create mode 100644 api/basic_json/operator_spaceship.md create mode 100644 api/basic_json/operator_spaceship/index.md create mode 100644 api/basic_json/operator_value_t.md create mode 100644 api/basic_json/operator_value_t/index.md create mode 100644 api/basic_json/other_error.md create mode 100644 api/basic_json/other_error/index.md create mode 100644 api/basic_json/out_of_range.md create mode 100644 api/basic_json/out_of_range/index.md create mode 100644 api/basic_json/parse.md create mode 100644 api/basic_json/parse/index.md create mode 100644 api/basic_json/parse_error.md create mode 100644 api/basic_json/parse_error/index.md create mode 100644 api/basic_json/parse_event_t.md create mode 100644 api/basic_json/parse_event_t/index.md create mode 100644 api/basic_json/parser_callback_t.md create mode 100644 api/basic_json/parser_callback_t/index.md create mode 100644 api/basic_json/patch.md create mode 100644 api/basic_json/patch/index.md create mode 100644 api/basic_json/patch_inplace.md create mode 100644 api/basic_json/patch_inplace/index.md create mode 100644 api/basic_json/push_back.md create mode 100644 api/basic_json/push_back/index.md create mode 100644 api/basic_json/rbegin.md create mode 100644 api/basic_json/rbegin/index.md create mode 100644 api/basic_json/rend.md create mode 100644 api/basic_json/rend/index.md create mode 100644 api/basic_json/sax_parse.md create mode 100644 api/basic_json/sax_parse/index.md create mode 100644 api/basic_json/size.md create mode 100644 api/basic_json/size/index.md create mode 100644 api/basic_json/start_pos.md create mode 100644 api/basic_json/start_pos/index.md create mode 100644 api/basic_json/std_formatter.md create mode 100644 api/basic_json/std_formatter/index.md create mode 100644 api/basic_json/std_hash.md create mode 100644 api/basic_json/std_hash/index.md create mode 100644 api/basic_json/std_swap.md create mode 100644 api/basic_json/std_swap/index.md create mode 100644 api/basic_json/string_t.md create mode 100644 api/basic_json/string_t/index.md create mode 100644 api/basic_json/swap.md create mode 100644 api/basic_json/swap/index.md create mode 100644 api/basic_json/to_bjdata.md create mode 100644 api/basic_json/to_bjdata/index.md create mode 100644 api/basic_json/to_bson.md create mode 100644 api/basic_json/to_bson/index.md create mode 100644 api/basic_json/to_cbor.md create mode 100644 api/basic_json/to_cbor/index.md create mode 100644 api/basic_json/to_msgpack.md create mode 100644 api/basic_json/to_msgpack/index.md create mode 100644 api/basic_json/to_string.md create mode 100644 api/basic_json/to_string/index.md create mode 100644 api/basic_json/to_ubjson.md create mode 100644 api/basic_json/to_ubjson/index.md create mode 100644 api/basic_json/type.md create mode 100644 api/basic_json/type/index.md create mode 100644 api/basic_json/type_error.md create mode 100644 api/basic_json/type_error/index.md create mode 100644 api/basic_json/type_name.md create mode 100644 api/basic_json/type_name/index.md create mode 100644 api/basic_json/unflatten.md create mode 100644 api/basic_json/unflatten/index.md create mode 100644 api/basic_json/update.md create mode 100644 api/basic_json/update/index.md create mode 100644 api/basic_json/value.md create mode 100644 api/basic_json/value/index.md create mode 100644 api/basic_json/value_t.md create mode 100644 api/basic_json/value_t/index.md create mode 100644 api/basic_json/~basic_json.md create mode 100644 api/basic_json/~basic_json/index.md create mode 100644 api/byte_container_with_subtype.md create mode 100644 api/byte_container_with_subtype/byte_container_with_subtype.md create mode 100644 api/byte_container_with_subtype/byte_container_with_subtype/index.md create mode 100644 api/byte_container_with_subtype/clear_subtype.md create mode 100644 api/byte_container_with_subtype/clear_subtype/index.md create mode 100644 api/byte_container_with_subtype/has_subtype.md create mode 100644 api/byte_container_with_subtype/has_subtype/index.md create mode 100644 api/byte_container_with_subtype/index.md create mode 100644 api/byte_container_with_subtype/set_subtype.md create mode 100644 api/byte_container_with_subtype/set_subtype/index.md create mode 100644 api/byte_container_with_subtype/subtype.md create mode 100644 api/byte_container_with_subtype/subtype/index.md create mode 100644 api/json.md create mode 100644 api/json/index.md create mode 100644 api/json_pointer.md create mode 100644 api/json_pointer/back.md create mode 100644 api/json_pointer/back/index.md create mode 100644 api/json_pointer/empty.md create mode 100644 api/json_pointer/empty/index.md create mode 100644 api/json_pointer/front.md create mode 100644 api/json_pointer/front/index.md create mode 100644 api/json_pointer/index.md create mode 100644 api/json_pointer/json_pointer.md create mode 100644 api/json_pointer/json_pointer/index.md create mode 100644 api/json_pointer/operator_eq.md create mode 100644 api/json_pointer/operator_eq/index.md create mode 100644 api/json_pointer/operator_ne.md create mode 100644 api/json_pointer/operator_ne/index.md create mode 100644 api/json_pointer/operator_slash.md create mode 100644 api/json_pointer/operator_slash/index.md create mode 100644 api/json_pointer/operator_slasheq.md create mode 100644 api/json_pointer/operator_slasheq/index.md create mode 100644 api/json_pointer/operator_string_t.md create mode 100644 api/json_pointer/operator_string_t/index.md create mode 100644 api/json_pointer/parent_pointer.md create mode 100644 api/json_pointer/parent_pointer/index.md create mode 100644 api/json_pointer/pop_back.md create mode 100644 api/json_pointer/pop_back/index.md create mode 100644 api/json_pointer/pop_front.md create mode 100644 api/json_pointer/pop_front/index.md create mode 100644 api/json_pointer/push_back.md create mode 100644 api/json_pointer/push_back/index.md create mode 100644 api/json_pointer/push_front.md create mode 100644 api/json_pointer/push_front/index.md create mode 100644 api/json_pointer/string_t.md create mode 100644 api/json_pointer/string_t/index.md create mode 100644 api/json_pointer/to_string.md create mode 100644 api/json_pointer/to_string/index.md create mode 100644 api/json_sax.md create mode 100644 api/json_sax/binary.md create mode 100644 api/json_sax/binary/index.md create mode 100644 api/json_sax/boolean.md create mode 100644 api/json_sax/boolean/index.md create mode 100644 api/json_sax/end_array.md create mode 100644 api/json_sax/end_array/index.md create mode 100644 api/json_sax/end_object.md create mode 100644 api/json_sax/end_object/index.md create mode 100644 api/json_sax/index.md create mode 100644 api/json_sax/key.md create mode 100644 api/json_sax/key/index.md create mode 100644 api/json_sax/null.md create mode 100644 api/json_sax/null/index.md create mode 100644 api/json_sax/number_float.md create mode 100644 api/json_sax/number_float/index.md create mode 100644 api/json_sax/number_integer.md create mode 100644 api/json_sax/number_integer/index.md create mode 100644 api/json_sax/number_unsigned.md create mode 100644 api/json_sax/number_unsigned/index.md create mode 100644 api/json_sax/parse_error.md create mode 100644 api/json_sax/parse_error/index.md create mode 100644 api/json_sax/start_array.md create mode 100644 api/json_sax/start_array/index.md create mode 100644 api/json_sax/start_object.md create mode 100644 api/json_sax/start_object/index.md create mode 100644 api/json_sax/string.md create mode 100644 api/json_sax/string/index.md create mode 100644 api/macros.md create mode 100644 api/macros/index.md create mode 100644 api/macros/json_assert.md create mode 100644 api/macros/json_assert/index.md create mode 100644 api/macros/json_brace_init_copy_semantics.md create mode 100644 api/macros/json_brace_init_copy_semantics/index.md create mode 100644 api/macros/json_diagnostic_positions.md create mode 100644 api/macros/json_diagnostic_positions/index.md create mode 100644 api/macros/json_diagnostics.md create mode 100644 api/macros/json_diagnostics/index.md create mode 100644 api/macros/json_disable_enum_serialization.md create mode 100644 api/macros/json_disable_enum_serialization/index.md create mode 100644 api/macros/json_has_cpp_11.md create mode 100644 api/macros/json_has_cpp_11/index.md create mode 100644 api/macros/json_has_filesystem.md create mode 100644 api/macros/json_has_filesystem/index.md create mode 100644 api/macros/json_has_ranges.md create mode 100644 api/macros/json_has_ranges/index.md create mode 100644 api/macros/json_has_static_rtti.md create mode 100644 api/macros/json_has_static_rtti/index.md create mode 100644 api/macros/json_has_std_format.md create mode 100644 api/macros/json_has_std_format/index.md create mode 100644 api/macros/json_has_three_way_comparison.md create mode 100644 api/macros/json_has_three_way_comparison/index.md create mode 100644 api/macros/json_no_io.md create mode 100644 api/macros/json_no_io/index.md create mode 100644 api/macros/json_noexception.md create mode 100644 api/macros/json_noexception/index.md create mode 100644 api/macros/json_skip_library_version_check.md create mode 100644 api/macros/json_skip_library_version_check/index.md create mode 100644 api/macros/json_skip_unsupported_compiler_check.md create mode 100644 api/macros/json_skip_unsupported_compiler_check/index.md create mode 100644 api/macros/json_throw_user.md create mode 100644 api/macros/json_throw_user/index.md create mode 100644 api/macros/json_use_global_udls.md create mode 100644 api/macros/json_use_global_udls/index.md create mode 100644 api/macros/json_use_implicit_conversions.md create mode 100644 api/macros/json_use_implicit_conversions/index.md create mode 100644 api/macros/json_use_legacy_discarded_value_comparison.md create mode 100644 api/macros/json_use_legacy_discarded_value_comparison/index.md create mode 100644 api/macros/nlohmann_define_derived_type.md create mode 100644 api/macros/nlohmann_define_derived_type/index.md create mode 100644 api/macros/nlohmann_define_type_intrusive.md create mode 100644 api/macros/nlohmann_define_type_intrusive/index.md create mode 100644 api/macros/nlohmann_define_type_non_intrusive.md create mode 100644 api/macros/nlohmann_define_type_non_intrusive/index.md create mode 100644 api/macros/nlohmann_define_type_with_names.md create mode 100644 api/macros/nlohmann_define_type_with_names/index.md create mode 100644 api/macros/nlohmann_json_namespace.md create mode 100644 api/macros/nlohmann_json_namespace/index.md create mode 100644 api/macros/nlohmann_json_namespace_begin.md create mode 100644 api/macros/nlohmann_json_namespace_begin/index.md create mode 100644 api/macros/nlohmann_json_namespace_no_version.md create mode 100644 api/macros/nlohmann_json_namespace_no_version/index.md create mode 100644 api/macros/nlohmann_json_serialize_enum.md create mode 100644 api/macros/nlohmann_json_serialize_enum/index.md create mode 100644 api/macros/nlohmann_json_serialize_enum_strict.md create mode 100644 api/macros/nlohmann_json_serialize_enum_strict/index.md create mode 100644 api/macros/nlohmann_json_version_major.md create mode 100644 api/macros/nlohmann_json_version_major/index.md create mode 100644 api/operator_gtgt.md create mode 100644 api/operator_gtgt/index.md create mode 100644 api/operator_literal_json.md create mode 100644 api/operator_literal_json/index.md create mode 100644 api/operator_literal_json_pointer.md create mode 100644 api/operator_literal_json_pointer/index.md create mode 100644 api/operator_ltlt.md create mode 100644 api/operator_ltlt/index.md create mode 100644 api/ordered_json.md create mode 100644 api/ordered_json/index.md create mode 100644 api/ordered_map.md create mode 100644 api/ordered_map/index.md create mode 100644 community.md create mode 100644 community/code_of_conduct.md create mode 100644 community/code_of_conduct/index.md create mode 100644 community/contribution_guidelines.md create mode 100644 community/contribution_guidelines/index.md create mode 100644 community/governance.md create mode 100644 community/governance/index.md create mode 100644 community/index.md create mode 100644 community/quality_assurance.md create mode 100644 community/quality_assurance/index.md create mode 100644 community/security_policy.md create mode 100644 community/security_policy/index.md create mode 100644 features.md create mode 100644 features/arbitrary_types.md create mode 100644 features/arbitrary_types/index.md create mode 100644 features/assertions.md create mode 100644 features/assertions/index.md create mode 100644 features/binary_formats.md create mode 100644 features/binary_formats/bjdata.md create mode 100644 features/binary_formats/bjdata/index.md create mode 100644 features/binary_formats/bson.md create mode 100644 features/binary_formats/bson/index.md create mode 100644 features/binary_formats/cbor.md create mode 100644 features/binary_formats/cbor/index.md create mode 100644 features/binary_formats/index.md create mode 100644 features/binary_formats/messagepack.md create mode 100644 features/binary_formats/messagepack/index.md create mode 100644 features/binary_formats/ubjson.md create mode 100644 features/binary_formats/ubjson/index.md create mode 100644 features/binary_values.md create mode 100644 features/binary_values/index.md create mode 100644 features/comments.md create mode 100644 features/comments/index.md create mode 100644 features/conversions.md create mode 100644 features/conversions/index.md create mode 100644 features/creating_values.md create mode 100644 features/creating_values/index.md create mode 100644 features/element_access.md create mode 100644 features/element_access/checked_access.md create mode 100644 features/element_access/checked_access/index.md create mode 100644 features/element_access/default_value.md create mode 100644 features/element_access/default_value/index.md create mode 100644 features/element_access/index.md create mode 100644 features/element_access/unchecked_access.md create mode 100644 features/element_access/unchecked_access/index.md create mode 100644 features/enum_conversion.md create mode 100644 features/enum_conversion/index.md create mode 100644 features/index.md create mode 100644 features/iterators.md create mode 100644 features/iterators/index.md create mode 100644 features/json_patch.md create mode 100644 features/json_patch/index.md create mode 100644 features/json_pointer.md create mode 100644 features/json_pointer/index.md create mode 100644 features/macros.md create mode 100644 features/macros/index.md create mode 100644 features/merge_patch.md create mode 100644 features/merge_patch/index.md create mode 100644 features/modifying_values.md create mode 100644 features/modifying_values/index.md create mode 100644 features/modules.md create mode 100644 features/modules/index.md create mode 100644 features/namespace.md create mode 100644 features/namespace/index.md create mode 100644 features/object_order.md create mode 100644 features/object_order/index.md create mode 100644 features/parsing.md create mode 100644 features/parsing/index.md create mode 100644 features/parsing/json_lines.md create mode 100644 features/parsing/json_lines/index.md create mode 100644 features/parsing/parse_exceptions.md create mode 100644 features/parsing/parse_exceptions/index.md create mode 100644 features/parsing/parser_callbacks.md create mode 100644 features/parsing/parser_callbacks/index.md create mode 100644 features/parsing/sax_interface.md create mode 100644 features/parsing/sax_interface/index.md create mode 100644 features/serialization.md create mode 100644 features/serialization/index.md create mode 100644 features/trailing_commas.md create mode 100644 features/trailing_commas/index.md create mode 100644 features/types.md create mode 100644 features/types/index.md create mode 100644 features/types/number_handling.md create mode 100644 features/types/number_handling/index.md create mode 100644 home/architecture.md create mode 100644 home/architecture/index.md create mode 100644 home/customers.md create mode 100644 home/customers/index.md create mode 100644 home/design_goals.md create mode 100644 home/design_goals/index.md create mode 100644 home/exceptions.md create mode 100644 home/exceptions/index.md create mode 100644 home/faq.md create mode 100644 home/faq/index.md create mode 100644 home/license.md create mode 100644 home/license/index.md create mode 100644 home/releases.md create mode 100644 home/releases/index.md create mode 100644 home/sponsors.md create mode 100644 home/sponsors/index.md create mode 100644 index.md create mode 100644 integration.md create mode 100644 integration/cmake.md create mode 100644 integration/cmake/index.md create mode 100644 integration/index.md create mode 100644 integration/migration_guide.md create mode 100644 integration/migration_guide/index.md create mode 100644 integration/package_managers.md create mode 100644 integration/package_managers/index.md create mode 100644 integration/pkg-config.md create mode 100644 integration/pkg-config/index.md create mode 100644 llms.txt create mode 100644 robots.txt diff --git a/..md b/..md new file mode 100644 index 000000000..0e49c836c --- /dev/null +++ b/..md @@ -0,0 +1,3 @@ +# JSON for Modern C++ + +![](images/json.gif) diff --git a/api/adl_serializer.md b/api/adl_serializer.md new file mode 100644 index 000000000..e83b66dec --- /dev/null +++ b/api/adl_serializer.md @@ -0,0 +1,35 @@ +# nlohmann::adl_serializer + +```cpp +template +struct adl_serializer; +``` + +Serializer that uses ADL ([Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)) to choose +`to_json`/`from_json` functions from the types' namespaces. + +It is implemented similarly to + +```cpp +template +struct adl_serializer { + template + static void to_json(BasicJsonType& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +## Member functions + +- [**from_json**](from_json.md) - convert a JSON value to any value type +- [**to_json**](to_json.md) - convert any value type to a JSON value + +## Version history + +- Added in version 2.1.0. diff --git a/api/adl_serializer/from_json.md b/api/adl_serializer/from_json.md new file mode 100644 index 000000000..72df961f4 --- /dev/null +++ b/api/adl_serializer/from_json.md @@ -0,0 +1,74 @@ +# nlohmann::adl_serializer::from_json + +```cpp +// (1) +template +static auto from_json(BasicJsonType && j, TargetType& val) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), val))) +-> decltype(::nlohmann::from_json(std::forward(j), val), void()) + +// (2) +template +static auto from_json(BasicJsonType && j) noexcept( +noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) +-> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) +``` + +This function is usually called by the [`get()`](../basic_json/get.md) function of the [basic_json](../basic_json/index.md) +class (either explicitly or via the conversion operators). + +1. This function is chosen for default-constructible value types. +2. This function is chosen for value types which are not default-constructible. + +## Parameters + +`j` (in) +: JSON value to read from + +`val` (out) +: value to write to + +## Return value + +1. (none) -- the converted value is written to the output parameter `val`. +2. the JSON value `j` converted to `TargetType` + +## Examples + +??? example "Example: (1) Default-constructible type" + + The example below shows how a `from_json` function can be implemented for a user-defined type. This function is + called by the `adl_serializer` when `get()` is called. + + ```cpp + --8<-- "examples/from_json__default_constructible.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_json__default_constructible.output" + ``` + +??? example "Example: (2) Non-default-constructible type" + + The example below shows how a `from_json` is implemented as part of a specialization of the `adl_serializer` to + realize the conversion of a non-default-constructible type. + + ```cpp + --8<-- "examples/from_json__non_default_constructible.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_json__non_default_constructible.output" + ``` + +## See also + +- [to_json](to_json.md) + +## Version history + +- Added in version 2.1.0. diff --git a/api/adl_serializer/from_json/index.html b/api/adl_serializer/from_json/index.html index eee1fd1fd..01224f738 100644 --- a/api/adl_serializer/from_json/index.html +++ b/api/adl_serializer/from_json/index.html @@ -101,4 +101,4 @@ std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl; }

Output:

Ned Flanders (60) lives in 744 Evergreen Terrace
-

See also

Version history

  • Added in version 2.1.0.
\ No newline at end of file +

See also

Version history

  • Added in version 2.1.0.
\ No newline at end of file diff --git a/api/adl_serializer/from_json/index.md b/api/adl_serializer/from_json/index.md new file mode 100644 index 000000000..4ae04e8c1 --- /dev/null +++ b/api/adl_serializer/from_json/index.md @@ -0,0 +1,157 @@ +# nlohmann::adl_serializer::from_json + +``` +// (1) +template +static auto from_json(BasicJsonType && j, TargetType& val) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), val))) +-> decltype(::nlohmann::from_json(std::forward(j), val), void()) + +// (2) +template +static auto from_json(BasicJsonType && j) noexcept( +noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) +-> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) +``` + +This function is usually called by the [`get()`](https://json.nlohmann.me/api/basic_json/get/index.md) function of the [basic_json](https://json.nlohmann.me/api/basic_json/index.md) class (either explicitly or via the conversion operators). + +1. This function is chosen for default-constructible value types. +1. This function is chosen for value types which are not default-constructible. + +## Parameters + +`j` (in) : JSON value to read from + +`val` (out) : value to write to + +## Return value + +1. (none) -- the converted value is written to the output parameter `val`. +1. the JSON value `j` converted to `TargetType` + +## Examples + +Example: (1) Default-constructible type + +The example below shows how a `from_json` function can be implemented for a user-defined type. This function is called by the `adl_serializer` when `get()` is called. + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +// a simple struct to model a person +struct person +{ + std::string name; + std::string address; + int age; +}; +} // namespace ns + +namespace ns +{ +void from_json(const json& j, person& p) +{ + j.at("name").get_to(p.name); + j.at("address").get_to(p.address); + j.at("age").get_to(p.age); +} +} // namespace ns + +int main() +{ + json j; + j["name"] = "Ned Flanders"; + j["address"] = "744 Evergreen Terrace"; + j["age"] = 60; + + auto p = j.get(); + + std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl; +} +``` + +Output: + +``` +Ned Flanders (60) lives in 744 Evergreen Terrace +``` + +Example: (2) Non-default-constructible type + +The example below shows how a `from_json` is implemented as part of a specialization of the `adl_serializer` to realize the conversion of a non-default-constructible type. + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +// a simple struct to model a person (not default constructible) +struct person +{ + person(std::string n, std::string a, int aa) + : name(std::move(n)), address(std::move(a)), age(aa) + {} + + std::string name; + std::string address; + int age; +}; +} // namespace ns + +namespace nlohmann +{ +template <> +struct adl_serializer +{ + static ns::person from_json(const json& j) + { + return {j.at("name"), j.at("address"), j.at("age")}; + } + + // Here's the catch! You must provide a to_json method! Otherwise, you + // will not be able to convert person to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, ns::person p) + { + j["name"] = p.name; + j["address"] = p.address; + j["age"] = p.age; + } +}; +} // namespace nlohmann + +int main() +{ + json j; + j["name"] = "Ned Flanders"; + j["address"] = "744 Evergreen Terrace"; + j["age"] = 60; + + auto p = j.get(); + + std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl; +} +``` + +Output: + +``` +Ned Flanders (60) lives in 744 Evergreen Terrace +``` + +## See also + +- [to_json](https://json.nlohmann.me/api/adl_serializer/to_json/index.md) + +## Version history + +- Added in version 2.1.0. diff --git a/api/adl_serializer/index.html b/api/adl_serializer/index.html index 6b611e9d6..1157ff4ab 100644 --- a/api/adl_serializer/index.html +++ b/api/adl_serializer/index.html @@ -12,4 +12,4 @@ // same thing, but with the "from_json" method } }; -

Member functions

  • from_json - convert a JSON value to any value type
  • to_json - convert any value type to a JSON value

Version history

  • Added in version 2.1.0.
\ No newline at end of file +

Member functions

  • from_json - convert a JSON value to any value type
  • to_json - convert any value type to a JSON value

Version history

  • Added in version 2.1.0.
\ No newline at end of file diff --git a/api/adl_serializer/index.md b/api/adl_serializer/index.md new file mode 100644 index 000000000..0482fba5c --- /dev/null +++ b/api/adl_serializer/index.md @@ -0,0 +1,34 @@ +# nlohmann::adl_serializer + +``` +template +struct adl_serializer; +``` + +Serializer that uses ADL ([Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)) to choose `to_json`/`from_json` functions from the types' namespaces. + +It is implemented similarly to + +``` +template +struct adl_serializer { + template + static void to_json(BasicJsonType& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +## Member functions + +- [**from_json**](https://json.nlohmann.me/api/adl_serializer/from_json/index.md) - convert a JSON value to any value type +- [**to_json**](https://json.nlohmann.me/api/adl_serializer/to_json/index.md) - convert any value type to a JSON value + +## Version history + +- Added in version 2.1.0. diff --git a/api/adl_serializer/to_json.md b/api/adl_serializer/to_json.md new file mode 100644 index 000000000..da9765186 --- /dev/null +++ b/api/adl_serializer/to_json.md @@ -0,0 +1,43 @@ +# nlohmann::adl_serializer::to_json + +```cpp +template +static auto to_json(BasicJsonType& j, TargetType && val) noexcept( + noexcept(::nlohmann::to_json(j, std::forward(val)))) +-> decltype(::nlohmann::to_json(j, std::forward(val)), void()) +``` + +This function is usually called by the constructors of the [basic_json](../basic_json/index.md) class. + +## Parameters + +`j` (out) +: JSON value to write to + +`val` (in) +: value to read from + +## Examples + +??? example + + The example below shows how a `to_json` function can be implemented for a user-defined type. This function is called + by the `adl_serializer` when the constructor `basic_json(ns::person)` is called. + + ```cpp + --8<-- "examples/to_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_json.output" + ``` + +## See also + +- [from_json](from_json.md) + +## Version history + +- Added in version 2.1.0. diff --git a/api/adl_serializer/to_json/index.html b/api/adl_serializer/to_json/index.html index 2be2ba9c4..5b00a72f2 100644 --- a/api/adl_serializer/to_json/index.html +++ b/api/adl_serializer/to_json/index.html @@ -35,4 +35,4 @@ std::cout << j << std::endl; }

Output:

{"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
-

See also

Version history

  • Added in version 2.1.0.
\ No newline at end of file +

See also

Version history

  • Added in version 2.1.0.
\ No newline at end of file diff --git a/api/adl_serializer/to_json/index.md b/api/adl_serializer/to_json/index.md new file mode 100644 index 000000000..e2b453c4e --- /dev/null +++ b/api/adl_serializer/to_json/index.md @@ -0,0 +1,71 @@ +# nlohmann::adl_serializer::to_json + +``` +template +static auto to_json(BasicJsonType& j, TargetType && val) noexcept( + noexcept(::nlohmann::to_json(j, std::forward(val)))) +-> decltype(::nlohmann::to_json(j, std::forward(val)), void()) +``` + +This function is usually called by the constructors of the [basic_json](https://json.nlohmann.me/api/basic_json/index.md) class. + +## Parameters + +`j` (out) : JSON value to write to + +`val` (in) : value to read from + +## Examples + +Example + +The example below shows how a `to_json` function can be implemented for a user-defined type. This function is called by the `adl_serializer` when the constructor `basic_json(ns::person)` is called. + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +// a simple struct to model a person +struct person +{ + std::string name; + std::string address; + int age; +}; +} // namespace ns + +namespace ns +{ +void to_json(json& j, const person& p) +{ + j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} }; +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + json j = p; + + std::cout << j << std::endl; +} +``` + +Output: + +``` +{"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +``` + +## See also + +- [from_json](https://json.nlohmann.me/api/adl_serializer/from_json/index.md) + +## Version history + +- Added in version 2.1.0. diff --git a/api/basic_json.md b/api/basic_json.md new file mode 100644 index 000000000..bd33f31ac --- /dev/null +++ b/api/basic_json.md @@ -0,0 +1,338 @@ +# nlohmann::basic_json + +Defined in header `` + +```cpp +template< + template class ObjectType = std::map, + template class ArrayType = std::vector, + class StringType = std::string, + class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = adl_serializer, + class BinaryType = std::vector, + class CustomBaseClass = void +> +class basic_json; +``` + +## Template parameters + +| Template parameter | Description | Derived type | +|----------------------|---------------------------------------------------------------------------|---------------------------------------------| +| `ObjectType` | type for JSON objects | [`object_t`](object_t.md) | +| `ArrayType` | type for JSON arrays | [`array_t`](array_t.md) | +| `StringType` | type for JSON strings and object keys | [`string_t`](string_t.md) | +| `BooleanType` | type for JSON booleans | [`boolean_t`](boolean_t.md) | +| `NumberIntegerType` | type for JSON integer numbers | [`number_integer_t`](number_integer_t.md) | +| `NumberUnsignedType` | type for JSON unsigned integer numbers | [`number_unsigned_t`](number_unsigned_t.md) | +| `NumberFloatType` | type for JSON floating-point numbers | [`number_float_t`](number_float_t.md) | +| `AllocatorType` | type of the allocator to use | | +| `JSONSerializer` | the serializer to resolve internal calls to `to_json()` and `from_json()` | [`json_serializer`](json_serializer.md) | +| `BinaryType` | type for binary arrays | [`binary_t`](binary_t.md) | +| `CustomBaseClass` | extension point for user code | [`json_base_class_t`](json_base_class_t.md) | + +## Specializations + +- [**json**](../json.md) - default specialization +- [**ordered_json**](../ordered_json.md) - a specialization that maintains the insertion order of object keys + +## Iterator invalidation + +All operations that add values to an **array** ([`push_back`](push_back.md) , [`operator+=`](operator+=.md), +[`emplace_back`](emplace_back.md), [`insert`](insert.md), and [`operator[]`](operator%5B%5D.md) for a non-existing +index) can yield a reallocation, in which case all iterators (including the [`end()`](end.md) iterator) and all +references to the elements are invalidated. + +For [`ordered_json`](../ordered_json.md), also all operations that add a value to an **object** +([`push_back`](push_back.md), [`operator+=`](operator+=.md), [`emplace`](emplace.md), [`insert`](insert.md), +[`update`](update.md), and [`operator[]`](operator%5B%5D.md) for a non-existing key) can yield a reallocation, in +which case all iterators (including the [`end()`](end.md) iterator) and all references to the elements are invalidated. + +## Requirements + +The class satisfies the following concept requirements: + +### Basic + +- [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): JSON values can be + default-constructed. The result will be a JSON null value. +- [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): A JSON value can be constructed + from an rvalue argument. +- [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): A JSON value can be + copy-constructed from an lvalue expression. +- [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): A JSON value can be assigned from an + rvalue argument. +- [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): A JSON value can be copy-assigned from + an lvalue expression. +- [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): JSON values can be destructed. + +### Layout + +- [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): JSON values have + [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): All non-static data + members are private and standard layout types, the class has no virtual functions or (virtual) base classes. + +### Library-wide + +- [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): JSON values can be compared with + `==`, see [`operator==`](operator_eq.md). +- [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): JSON values can be compared with + `<`, see [`operator<`](operator_le.md). +- [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): Any JSON lvalue or rvalue of can be swapped with + any lvalue or rvalue of other compatible types, using unqualified function `swap`. +- [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): JSON values can be compared against + `std::nullptr_t` objects which are used to model the `null` value. + +### Container + +- [Container](https://en.cppreference.com/w/cpp/named_req/Container): JSON values can be used like STL containers and + provide iterator access. +- [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer): JSON values can be used like + STL containers and provide reverse iterator access. + +## Member types + +- [**adl_serializer**](../adl_serializer/index.md) - the default serializer +- [**value_t**](value_t.md) - the JSON type enumeration +- [**json_pointer**](../json_pointer/index.md) - JSON Pointer implementation +- [**json_serializer**](json_serializer.md) - type of the serializer to for conversions from/to JSON +- [**error_handler_t**](error_handler_t.md) - type to choose behavior on decoding errors +- [**cbor_tag_handler_t**](cbor_tag_handler_t.md) - type to choose how to handle CBOR tags +- **initializer_list_t** - type for initializer lists of `basic_json` values +- [**input_format_t**](input_format_t.md) - type to choose the format to parse +- [**json_sax_t**](../json_sax/index.md) - type for SAX events + +### Exceptions + +- [**exception**](exception.md) - general exception of the `basic_json` class + - [**parse_error**](parse_error.md) - exception indicating a parse error + - [**invalid_iterator**](invalid_iterator.md) - exception indicating errors with iterators + - [**type_error**](type_error.md) - exception indicating executing a member function with a wrong type + - [**out_of_range**](out_of_range.md) - exception indicating access out of the defined range + - [**other_error**](other_error.md) - exception indicating other library errors + +### Container types + +| Type | Definition | +|--------------------------|-----------------------------------------------------------------------------------------------------------| +| `value_type` | `#!cpp basic_json` | +| `reference` | `#!cpp value_type&` | +| `const_reference` | `#!cpp const value_type&` | +| `difference_type` | `#!cpp std::ptrdiff_t` | +| `size_type` | `#!cpp std::size_t` | +| `allocator_type` | `#!cpp AllocatorType` | +| `pointer` | `#!cpp std::allocator_traits::pointer` | +| `const_pointer` | `#!cpp std::allocator_traits::const_pointer` | +| `iterator` | [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| `const_iterator` | constant [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| `reverse_iterator` | reverse iterator, derived from `iterator` | +| `const_reverse_iterator` | reverse iterator, derived from `const_iterator` | +| `iteration_proxy` | helper type for [`items`](items.md) function | + +### JSON value data types + +- [**array_t**](array_t.md) - type for arrays +- [**binary_t**](binary_t.md) - type for binary arrays +- [**boolean_t**](boolean_t.md) - type for booleans +- [**default_object_comparator_t**](default_object_comparator_t.md) - default comparator for objects +- [**number_float_t**](number_float_t.md) - type for numbers (floating-point) +- [**number_integer_t**](number_integer_t.md) - type for numbers (integer) +- [**number_unsigned_t**](number_unsigned_t.md) - type for numbers (unsigned) +- [**object_comparator_t**](object_comparator_t.md) - comparator for objects +- [**object_t**](object_t.md) - type for objects +- [**string_t**](string_t.md) - type for strings + +### Parser callback + +- [**parse_event_t**](parse_event_t.md) - parser event types +- [**parser_callback_t**](parser_callback_t.md) - per-element parser callback type + +## Member functions + +- [(constructor)](basic_json.md) +- [(destructor)](~basic_json.md) +- [**operator=**](operator=.md) - copy assignment +- [**array**](array.md) (_static_) - explicitly create an array +- [**binary**](binary.md) (_static_) - explicitly create a binary array +- [**object**](object.md) (_static_) - explicitly create an object + +### Object inspection + +Functions to inspect the type of a JSON value. + +- [**type**](type.md) - return the type of the JSON value +- [**operator value_t**](operator_value_t.md) - return the type of the JSON value +- [**type_name**](type_name.md) - return the type as string +- [**is_primitive**](is_primitive.md) - return whether the type is primitive +- [**is_structured**](is_structured.md) - return whether the type is structured +- [**is_null**](is_null.md) - return whether the value is null +- [**is_boolean**](is_boolean.md) - return whether the value is a boolean +- [**is_number**](is_number.md) - return whether the value is a number +- [**is_number_integer**](is_number_integer.md) - return whether the value is an integer number +- [**is_number_unsigned**](is_number_unsigned.md) - return whether the value is an unsigned integer number +- [**is_number_float**](is_number_float.md) - return whether the value is a floating-point number +- [**is_object**](is_object.md) - return whether the value is an object +- [**is_array**](is_array.md) - return whether the value is an array +- [**is_string**](is_string.md) - return whether the value is a string +- [**is_binary**](is_binary.md) - return whether the value is a binary array +- [**is_discarded**](is_discarded.md) - return whether the value is discarded + +Optional functions to access the [diagnostic positions](../macros/json_diagnostic_positions.md). + +- [**start_pos**](start_pos.md) - return the start position of the value +- [**end_pos**](end_pos.md) - return the one past the end position of the value + +### Value access + +Direct access to the stored value of a JSON value. + +- [**get**](get.md) - get a value +- [**get_to**](get_to.md) - get a value and write it to a destination +- [**get_ptr**](get_ptr.md) - get a pointer value +- [**get_ref**](get_ref.md) - get a reference value +- [**operator ValueType**](operator_ValueType.md) - get a value +- [**get_binary**](get_binary.md) - get a binary value + +### Element access + +Access to the JSON value + +- [**at**](at.md) - access specified element with bounds checking +- [**operator[]**](operator[].md) - access specified element +- [**value**](value.md) - access specified object element with default value +- [**front**](front.md) - access the first element +- [**back**](back.md) - access the last element + +### Lookup + +- [**find**](find.md) - find an element in a JSON object +- [**count**](count.md) - returns the number of occurrences of a key in a JSON object +- [**contains**](contains.md) - check the existence of an element in a JSON object + +### Iterators + +- [**begin**](begin.md) - returns an iterator to the first element +- [**cbegin**](cbegin.md) - returns a const iterator to the first element +- [**end**](end.md) - returns an iterator to one past the last element +- [**cend**](cend.md) - returns a const iterator to one past the last element +- [**rbegin**](rbegin.md) - returns an iterator to the reverse-beginning +- [**rend**](rend.md) - returns an iterator to the reverse-end +- [**crbegin**](crbegin.md) - returns a const iterator to the reverse-beginning +- [**crend**](crend.md) - returns a const iterator to the reverse-end +- [**items**](items.md) - wrapper to access iterator member functions in range-based for + +### Capacity + +- [**empty**](empty.md) - checks whether the container is empty +- [**size**](size.md) - returns the number of elements +- [**max_size**](max_size.md) - returns the maximum possible number of elements + +### Modifiers + +- [**clear**](clear.md) - clears the contents +- [**push_back**](push_back.md) - add a value to an array/object +- [**operator+=**](operator+=.md) - add a value to an array/object +- [**emplace_back**](emplace_back.md) - add a value to an array +- [**emplace**](emplace.md) - add a value to an object if a key does not exist +- [**erase**](erase.md) - remove elements +- [**insert**](insert.md) - inserts elements +- [**update**](update.md) - updates a JSON object from another object, overwriting existing keys +- [**swap**](swap.md) - exchanges the values + +### Lexicographical comparison operators + +- [**operator==**](operator_eq.md) - comparison: equal +- [**operator!=**](operator_ne.md) - comparison: not equal +- [**operator<**](operator_lt.md) - comparison: less than +- [**operator>**](operator_gt.md) - comparison: greater than +- [**operator<=**](operator_le.md) - comparison: less than or equal +- [**operator>=**](operator_ge.md) - comparison: greater than or equal +- [**operator<=>**](operator_spaceship.md) - comparison: 3-way + +### Serialization / Dumping + +- [**dump**](dump.md) - serialization + +### Deserialization / Parsing + +- [**parse**](parse.md) (_static_) - deserialize from a compatible input +- [**accept**](accept.md) (_static_) - check if the input is valid JSON +- [**sax_parse**](sax_parse.md) (_static_) - generate SAX events + +### JSON Pointer functions + +- [**flatten**](flatten.md) - return flattened JSON value +- [**unflatten**](unflatten.md) - unflatten a previously flattened JSON value + +### JSON Patch functions + +- [**patch**](patch.md) - applies a JSON patch +- [**patch_inplace**](patch_inplace.md) - applies a JSON patch in place +- [**diff**](diff.md) (_static_) - creates a diff as a JSON patch + +### JSON Merge Patch functions + +- [**merge_patch**](merge_patch.md) - applies a JSON Merge Patch + +## Static functions + +- [**meta**](meta.md) - returns version information on the library +- [**get_allocator**](get_allocator.md) - returns the allocator associated with the container + +### Binary formats + +- [**from_bjdata**](from_bjdata.md) (_static_) - create a JSON value from an input in BJData format +- [**from_bson**](from_bson.md) (_static_) - create a JSON value from an input in BSON format +- [**from_cbor**](from_cbor.md) (_static_) - create a JSON value from an input in CBOR format +- [**from_msgpack**](from_msgpack.md) (_static_) - create a JSON value from an input in MessagePack format +- [**from_ubjson**](from_ubjson.md) (_static_) - create a JSON value from an input in UBJSON format +- [**to_bjdata**](to_bjdata.md) (_static_) - create a BJData serialization of a given JSON value +- [**to_bson**](to_bson.md) (_static_) - create a BSON serialization of a given JSON value +- [**to_cbor**](to_cbor.md) (_static_) - create a CBOR serialization of a given JSON value +- [**to_msgpack**](to_msgpack.md) (_static_) - create a MessagePack serialization of a given JSON value +- [**to_ubjson**](to_ubjson.md) (_static_) - create a UBJSON serialization of a given JSON value + +## Non-member functions + +- [**operator<<(std::ostream&)**](../operator_ltlt.md) - serialize to stream +- [**operator>>(std::istream&)**](../operator_gtgt.md) - deserialize from stream +- [**to_string**](to_string.md) - user-defined `to_string` function for JSON values +- [**format_as**](format_as.md) - user-defined `format_as` function for JSON values (fmt support) + +## Literals + +- [**operator""_json**](../operator_literal_json.md) - user-defined string literal for JSON values + +## Helper classes + +- [**std::formatter<basic_json>**](std_formatter.md) - make JSON values formattable with `std::format` +- [**std::hash<basic_json>**](std_hash.md) - return a hash value for a JSON object +- [**std::swap<basic_json>**](std_swap.md) - exchanges the values of two JSON objects + +## Examples + +??? example + + The example shows how the library is used. + + ```cpp + --8<-- "examples/README.cpp" + ``` + + Output: + + ```json + --8<-- "examples/README.output" + ``` + +## See also + +- [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259) + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/accept.md b/api/basic_json/accept.md new file mode 100644 index 000000000..9e495cdef --- /dev/null +++ b/api/basic_json/accept.md @@ -0,0 +1,121 @@ +# nlohmann::basic_json::accept + +```cpp +// (1) +template +static bool accept(InputType&& i, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); + +// (2) +template +static bool accept(IteratorType first, IteratorType last, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +Checks whether the input is valid JSON. + +1. Reads from a compatible input. +2. Reads from a pair of character iterators + + The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted + respectively as UTF-8, UTF-16, and UTF-32. + +Unlike the [`parse()`](parse.md) function, this function neither throws an exception in case of invalid JSON input +(i.e., a parse error) nor creates diagnostic information. + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `#!c FILE` pointer (throws if null) + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters (throws if null) + - a `std::string` + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type, for instance. + + - a pair of `std::string::iterator` or `std::vector::iterator` + - a pair of pointers such as `ptr` and `ptr + len` + +## Parameters + +`i` (in) +: Input to parse from. + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`ignore_trailing_commas` (in) +: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`first` (in) +: iterator to the start of the character range + +`last` (in) +: iterator to the end of the character range + +## Return value + +Whether the input is valid JSON. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an empty input like a null `#!c FILE*` or `#!c char*` pointer. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +## Examples + +??? example + + The example below demonstrates the `accept()` function reading from a string. + + ```cpp + --8<-- "examples/accept__string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/accept__string.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [sax_parse](sax_parse.md) - parse input using the SAX interface +- [operator>>](../operator_gtgt.md) - deserialize from stream + +## Version history + +- Added in version 3.0.0. +- Ignoring comments via `ignore_comments` added in version 3.9.0. +- Changed [runtime assertion](../../features/assertions.md) in case of `FILE*` null pointers to exception in version 3.12.0. +- Added `ignore_trailing_commas` in version 3.12.x. + +!!! warning "Deprecation" + + Overload (2) replaces calls to `accept` with a pair of iterators as their first parameter which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp accept({ptr, ptr+len}, ...);` with `#!cpp accept(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/api/basic_json/accept/index.html b/api/basic_json/accept/index.html index 821275153..f4d95772a 100644 --- a/api/basic_json/accept/index.html +++ b/api/basic_json/accept/index.html @@ -36,4 +36,4 @@ << json::accept(invalid_text) << '\n'; }

Output:

true false
-

See also

  • parse - deserialize from a compatible input
  • sax_parse - parse input using the SAX interface
  • operator>> - deserialize from stream

Version history

  • Added in version 3.0.0.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • Added ignore_trailing_commas in version 3.12.x.

Deprecation

Overload (2) replaces calls to accept with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like accept({ptr, ptr+len}, ...); with accept(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file +

See also

  • parse - deserialize from a compatible input
  • sax_parse - parse input using the SAX interface
  • operator>> - deserialize from stream

Version history

  • Added in version 3.0.0.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • Added ignore_trailing_commas in version 3.12.x.

Deprecation

Overload (2) replaces calls to accept with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like accept({ptr, ptr+len}, ...); with accept(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file diff --git a/api/basic_json/accept/index.md b/api/basic_json/accept/index.md new file mode 100644 index 000000000..5650c68b6 --- /dev/null +++ b/api/basic_json/accept/index.md @@ -0,0 +1,137 @@ +# nlohmann::basic_json::accept + +``` +// (1) +template +static bool accept(InputType&& i, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); + +// (2) +template +static bool accept(IteratorType first, IteratorType last, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +Checks whether the input is valid JSON. + +1. Reads from a compatible input. + +1. Reads from a pair of character iterators + + The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. + +Unlike the [`parse()`](https://json.nlohmann.me/api/basic_json/parse/index.md) function, this function neither throws an exception in case of invalid JSON input (i.e., a parse error) nor creates diagnostic information. + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer (throws if null) +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters (throws if null) +- a `std::string` +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. +``` + +`IteratorType` : a compatible iterator type, for instance. + +``` +- a pair of `std::string::iterator` or `std::vector::iterator` +- a pair of pointers such as `ptr` and `ptr + len` +``` + +## Parameters + +`i` (in) : Input to parse from. + +`ignore_comments` (in) : whether comments should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default) + +`ignore_trailing_commas` (in) : whether trailing commas in arrays or objects should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default) + +`first` (in) : iterator to the start of the character range + +`last` (in) : iterator to the end of the character range + +## Return value + +Whether the input is valid JSON. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +Throws [`parse_error.101`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error101) in case of an empty input like a null `FILE*` or `char*` pointer. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +## Examples + +Example + +The example below demonstrates the `accept()` function reading from a string. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a valid JSON text + auto valid_text = R"( + { + "numbers": [1, 2, 3] + } + )"; + + // an invalid JSON text + auto invalid_text = R"( + { + "strings": ["extra", "comma", ] + } + )"; + + std::cout << std::boolalpha + << json::accept(valid_text) << ' ' + << json::accept(invalid_text) << '\n'; +} +``` + +Output: + +``` +true false +``` + +## See also + +- [parse](https://json.nlohmann.me/api/basic_json/parse/index.md) - deserialize from a compatible input +- [sax_parse](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) - parse input using the SAX interface +- [operator>>](https://json.nlohmann.me/api/operator_gtgt/index.md) - deserialize from stream + +## Version history + +- Added in version 3.0.0. +- Ignoring comments via `ignore_comments` added in version 3.9.0. +- Changed [runtime assertion](https://json.nlohmann.me/features/assertions/index.md) in case of `FILE*` null pointers to exception in version 3.12.0. +- Added `ignore_trailing_commas` in version 3.12.x. + +Deprecation + +Overload (2) replaces calls to `accept` with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `accept({ptr, ptr+len}, ...);` with `accept(ptr, ptr+len, ...);`. + +You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated function. diff --git a/api/basic_json/array.md b/api/basic_json/array.md new file mode 100644 index 000000000..cbc5a723e --- /dev/null +++ b/api/basic_json/array.md @@ -0,0 +1,61 @@ +# nlohmann::basic_json::array + +```cpp +static basic_json array(initializer_list_t init = {}); +``` + +Creates a JSON array value from a given initializer list. That is, given a list of values `a, b, c`, creates the JSON +value `#!json [a, b, c]`. If the initializer list is empty, the empty array `#!json []` is created. + +## Parameters + +`init` (in) +: initializer list with JSON values to create an array from (optional) + +## Return value + +JSON array value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of `init`. + +## Notes + +This function is only needed to express two edge cases that cannot be realized with the initializer list constructor +([`basic_json(initializer_list_t, bool, value_t)`](basic_json.md)). These cases are: + +1. creating an array whose elements are all pairs whose first element is a string -- in this case, the initializer list + constructor would create an object, taking the first elements as keys +2. creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty + object + +## Examples + +??? example + + The following code shows an example for the `array` function. + + ```cpp + --8<-- "examples/array.cpp" + ``` + + Output: + + ```json + --8<-- "examples/array.output" + ``` + +## See also + +- [`basic_json(initializer_list_t)`](basic_json.md) - create a JSON value from an initializer list +- [`object`](object.md) - create a JSON object value from an initializer list +- [Creating JSON values](../../features/creating_values.md) - the article on creating JSON values + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/array/index.html b/api/basic_json/array/index.html index aae62442f..aec332d97 100644 --- a/api/basic_json/array/index.html +++ b/api/basic_json/array/index.html @@ -22,4 +22,4 @@ [] [1,2,3,4] [["one",1],["two",2]] -

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/array/index.md b/api/basic_json/array/index.md new file mode 100644 index 000000000..bfe4a3b4b --- /dev/null +++ b/api/basic_json/array/index.md @@ -0,0 +1,77 @@ +# nlohmann::basic_json::array + +``` +static basic_json array(initializer_list_t init = {}); +``` + +Creates a JSON array value from a given initializer list. That is, given a list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the initializer list is empty, the empty array `[]` is created. + +## Parameters + +`init` (in) : initializer list with JSON values to create an array from (optional) + +## Return value + +JSON array value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of `init`. + +## Notes + +This function is only needed to express two edge cases that cannot be realized with the initializer list constructor ([`basic_json(initializer_list_t, bool, value_t)`](https://json.nlohmann.me/api/basic_json/basic_json/index.md)). These cases are: + +1. creating an array whose elements are all pairs whose first element is a string -- in this case, the initializer list constructor would create an object, taking the first elements as keys +1. creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty object + +## Examples + +Example + +The following code shows an example for the `array` function. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON arrays + json j_no_init_list = json::array(); + json j_empty_init_list = json::array({}); + json j_nonempty_init_list = json::array({1, 2, 3, 4}); + json j_list_of_pairs = json::array({ {"one", 1}, {"two", 2} }); + + // serialize the JSON arrays + std::cout << j_no_init_list << '\n'; + std::cout << j_empty_init_list << '\n'; + std::cout << j_nonempty_init_list << '\n'; + std::cout << j_list_of_pairs << '\n'; +} +``` + +Output: + +``` +[] +[] +[1,2,3,4] +[["one",1],["two",2]] +``` + +## See also + +- [`basic_json(initializer_list_t)`](https://json.nlohmann.me/api/basic_json/basic_json/index.md) - create a JSON value from an initializer list +- [`object`](https://json.nlohmann.me/api/basic_json/object/index.md) - create a JSON object value from an initializer list +- [Creating JSON values](https://json.nlohmann.me/features/creating_values/index.md) - the article on creating JSON values + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/array_t.md b/api/basic_json/array_t.md new file mode 100644 index 000000000..dd2b901d5 --- /dev/null +++ b/api/basic_json/array_t.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::array_t + +```cpp +using array_t = ArrayType>; +``` + +The type used to store JSON arrays. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: +> An array is an ordered sequence of zero or more values. + +To store objects in C++, a type is defined by the template parameters explained below. + +## Template parameters + +`ArrayType` +: container type to store arrays (e.g., `std::vector` or `std::list`) + +`AllocatorType` +: the allocator to use for objects (e.g., `std::allocator`) + +## Notes + +#### Default type + +With the default values for `ArrayType` (`std::vector`) and `AllocatorType` (`std::allocator`), the default value for +`array_t` is: + +```cpp +std::vector< + basic_json, // value_type + std::allocator // allocator_type +> +``` + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the maximum depth of nesting. + +In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be +introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the +[`max_size`](max_size.md) function of a JSON array. + +#### Storage + +Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type +`#!cpp array_t*` must be dereferenced. + +## Examples + +??? example + + The following code shows that `array_t` is by default, a typedef to `#!cpp std::vector`. + + ```cpp + --8<-- "examples/array_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/array_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/array_t/index.html b/api/basic_json/array_t/index.html index 5e3ec8174..6cb6990b5 100644 --- a/api/basic_json/array_t/index.html +++ b/api/basic_json/array_t/index.html @@ -14,4 +14,4 @@ std::cout << std::boolalpha << std::is_same<std::vector<json>, json::array_t>::value << std::endl; }

Output:

true
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/array_t/index.md b/api/basic_json/array_t/index.md new file mode 100644 index 000000000..228d8aa43 --- /dev/null +++ b/api/basic_json/array_t/index.md @@ -0,0 +1,73 @@ +# nlohmann::basic_json::array_t + +``` +using array_t = ArrayType>; +``` + +The type used to store JSON arrays. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: + +> An array is an ordered sequence of zero or more values. + +To store objects in C++, a type is defined by the template parameters explained below. + +## Template parameters + +`ArrayType` : container type to store arrays (e.g., `std::vector` or `std::list`) + +`AllocatorType` : the allocator to use for objects (e.g., `std::allocator`) + +## Notes + +#### Default type + +With the default values for `ArrayType` (`std::vector`) and `AllocatorType` (`std::allocator`), the default value for `array_t` is: + +``` +std::vector< + basic_json, // value_type + std::allocator // allocator_type +> +``` + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the [`max_size`](https://json.nlohmann.me/api/basic_json/max_size/index.md) function of a JSON array. + +#### Storage + +Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type `array_t*` must be dereferenced. + +## Examples + +Example + +The following code shows that `array_t` is by default, a typedef to `std::vector`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same, json::array_t>::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/at.md b/api/basic_json/at.md new file mode 100644 index 000000000..2d1042cc8 --- /dev/null +++ b/api/basic_json/at.md @@ -0,0 +1,228 @@ +# nlohmann::basic_json::at + +```cpp +// (1) +reference at(size_type idx); +const_reference at(size_type idx) const; + +// (2) +reference at(const typename object_t::key_type& key); +const_reference at(const typename object_t::key_type& key) const; + +// (3) +template +reference at(KeyType&& key); +template +const_reference at(KeyType&& key) const; + +// (4) +reference at(const json_pointer& ptr); +const_reference at(const json_pointer& ptr) const; +``` + +1. Returns a reference to the array element at specified location `idx`, with bounds checking. +2. Returns a reference to the object element with specified key `key`, with bounds checking. +3. See 2. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. +4. Returns a reference to the element at specified JSON pointer `ptr`, with bounds checking. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`idx` (in) +: index of the element to access + +`key` (in) +: object key of the elements to access + +`ptr` (in) +: JSON pointer to the desired element + +## Return value + +1. reference to the element at index `idx` +2. reference to the element at key `key` +3. reference to the element at key `key` +4. reference to the element pointed to by `ptr` + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the JSON value is not an array; + in this case, calling `at` with an index makes no sense. See the example below. + - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if the index `idx` is out of + range of the array; that is, `idx >= size()`. See the example below. +2. The function can throw the following exceptions: + - Throws [`type_error.304`](../../home/exceptions.md#jsonexceptiontype_error304) if the JSON value is not an object; + in this case, calling `at` with a key makes no sense. See the example below. + - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if the key `key` is not + stored in the object; that is, `find(key) == end()`. See the example below. +3. See 2. +4. The function can throw the following exceptions: + - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in the passed + JSON pointer `ptr` begins with '0'. See the example below. + - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in the passed + JSON pointer `ptr` is not a number. See the example below. + - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index in the passed + JSON pointer `ptr` is out of range. See the example below. + - Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index '-' is used + in the passed JSON pointer `ptr`. As `at` provides checked access (and no elements are implicitly inserted), the + index '-' is always invalid. See the example below. + - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if the JSON pointer describes a + key of an object which cannot be found. See the example below. + - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if the JSON pointer `ptr` can + not be resolved. See the example below. + - Throws [`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) if an array index in the passed + JSON pointer `ptr` exceeds the range of `size_type` (e.g., on 32-bit platforms). + +## Complexity + +1. Constant. +2. Logarithmic in the size of the container. +3. Logarithmic in the size of the container. +4. Logarithmic in the size of the container. + +## Examples + +??? example "Example: (1) access specified array element with bounds checking" + + The example below shows how array elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__size_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__size_type.output" + ``` + +??? example "Example: (1) access specified array element with bounds checking" + + The example below shows how array elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__size_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__size_type_const.output" + ``` + +??? example "Example: (2) access specified object element with bounds checking" + + The example below shows how object elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__object_t_key_type.output" + ``` + +??? example "Example: (2) access specified object element with bounds checking" + + The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__object_t_key_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__object_t_key_type_const.output" + ``` + +??? example "Example: (3) access specified object element using string_view with bounds checking" + + The example below shows how object elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__keytype.c++17.output" + ``` + +??? example "Example: (3) access specified object element using string_view with bounds checking" + + The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__keytype_const.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__keytype_const.c++17.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer" + + The example below shows how object elements can be read and written using `at()`. It also demonstrates the different + exceptions that can be thrown. + + ```cpp + --8<-- "examples/at__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__json_pointer.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer" + + The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions + that can be thrown. + + ```cpp + --8<-- "examples/at__json_pointer_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/at__json_pointer_const.output" + ``` + +## See also + +- documentation on [checked access](../../features/element_access/checked_access.md) +- [`operator[]`](operator%5B%5D.md) for unchecked access by reference +- [`value`](value.md) for access with default value + +## Version history + +1. Added in version 1.0.0. +2. Added in version 1.0.0. +3. Added in version 3.11.0. +4. Added in version 2.0.0. diff --git a/api/basic_json/at/index.html b/api/basic_json/at/index.html index dffee47e1..f049b6d10 100644 --- a/api/basic_json/at/index.html +++ b/api/basic_json/at/index.html @@ -498,4 +498,4 @@ [json.exception.out_of_range.402] array index '-' (2) is out of range [json.exception.out_of_range.403] key 'foo' not found [json.exception.out_of_range.404] unresolved reference token 'foo' -

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 3.11.0.
  4. Added in version 2.0.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 3.11.0.
  4. Added in version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/at/index.md b/api/basic_json/at/index.md new file mode 100644 index 000000000..cb0007115 --- /dev/null +++ b/api/basic_json/at/index.md @@ -0,0 +1,668 @@ +# nlohmann::basic_json::at + +``` +// (1) +reference at(size_type idx); +const_reference at(size_type idx) const; + +// (2) +reference at(const typename object_t::key_type& key); +const_reference at(const typename object_t::key_type& key) const; + +// (3) +template +reference at(KeyType&& key); +template +const_reference at(KeyType&& key) const; + +// (4) +reference at(const json_pointer& ptr); +const_reference at(const json_pointer& ptr) const; +``` + +1. Returns a reference to the array element at specified location `idx`, with bounds checking. +1. Returns a reference to the object element with specified key `key`, with bounds checking. +1. See 2. This overload is only available if `KeyType` is comparable with `typename object_t::key_type` and `typename object_comparator_t::is_transparent` denotes a type. +1. Returns a reference to the element at specified JSON pointer `ptr`, with bounds checking. + +## Template parameters + +`KeyType` : A type for an object key other than [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) that is comparable with [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) using [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). This can also be a string view (C++17). + +## Parameters + +`idx` (in) : index of the element to access + +`key` (in) : object key of the elements to access + +`ptr` (in) : JSON pointer to the desired element + +## Return value + +1. reference to the element at index `idx` +1. reference to the element at key `key` +1. reference to the element at key `key` +1. reference to the element pointed to by `ptr` + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.304`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error304) if the JSON value is not an array; in this case, calling `at` with an index makes no sense. See the example below. + - Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if the index `idx` is out of range of the array; that is, `idx >= size()`. See the example below. +1. The function can throw the following exceptions: + - Throws [`type_error.304`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error304) if the JSON value is not an object; in this case, calling `at` with a key makes no sense. See the example below. + - Throws [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403) if the key `key` is not stored in the object; that is, `find(key) == end()`. See the example below. +1. See 2. +1. The function can throw the following exceptions: + - Throws [`parse_error.106`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error106) if an array index in the passed JSON pointer `ptr` begins with '0'. See the example below. + - Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) if an array index in the passed JSON pointer `ptr` is not a number. See the example below. + - Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if an array index in the passed JSON pointer `ptr` is out of range. See the example below. + - Throws [`out_of_range.402`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range402) if the array index '-' is used in the passed JSON pointer `ptr`. As `at` provides checked access (and no elements are implicitly inserted), the index '-' is always invalid. See the example below. + - Throws [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403) if the JSON pointer describes a key of an object which cannot be found. See the example below. + - Throws [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) if the JSON pointer `ptr` can not be resolved. See the example below. + - Throws [`out_of_range.410`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range410) if an array index in the passed JSON pointer `ptr` exceeds the range of `size_type` (e.g., on 32-bit platforms). + +## Complexity + +1. Constant. +1. Logarithmic in the size of the container. +1. Logarithmic in the size of the container. +1. Logarithmic in the size of the container. + +## Examples + +Example: (1) access specified array element with bounds checking + +The example below shows how array elements can be read and written using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON array + json array = {"first", "2nd", "third", "fourth"}; + + // output element at index 2 (third element) + std::cout << array.at(2) << '\n'; + + // change element at index 1 (second element) to "second" + array.at(1) = "second"; + + // output changed array + std::cout << array << '\n'; + + // exception type_error.304 + try + { + // use at() on a non-array type + json str = "I am a string"; + str.at(0) = "Another string"; + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to write beyond the array limit + array.at(5) = "sixth"; + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +"third" +["first","second","third","fourth"] +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.401] array index 5 is out of range +``` + +Example: (1) access specified array element with bounds checking + +The example below shows how array elements can be read using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON array + const json array = {"first", "2nd", "third", "fourth"}; + + // output element at index 2 (third element) + std::cout << array.at(2) << '\n'; + + // exception type_error.304 + try + { + // use at() on a non-array type + const json str = "I am a string"; + std::cout << str.at(0) << '\n'; + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to read beyond the array limit + std::cout << array.at(5) << '\n'; + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +"third" +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.401] array index 5 is out of range +``` + +Example: (2) access specified object element with bounds checking + +The example below shows how object elements can be read and written using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON object + json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" + std::cout << object.at("the ugly") << '\n'; + + // change element with key "the bad" + object.at("the bad") = "il cattivo"; + + // output changed array + std::cout << object << '\n'; + + // exception type_error.304 + try + { + // use at() on a non-object type + json str = "I am a string"; + str.at("the good") = "Another string"; + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to write at a nonexisting key + object.at("the fast") = "il rapido"; + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +"il brutto" +{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"} +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.403] key 'the fast' not found +``` + +Example: (2) access specified object element with bounds checking + +The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON object + const json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" + std::cout << object.at("the ugly") << '\n'; + + // exception type_error.304 + try + { + // use at() on a non-object type + const json str = "I am a string"; + std::cout << str.at("the good") << '\n'; + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to read from a nonexisting key + std::cout << object.at("the fast") << '\n'; + } + catch (const json::out_of_range) + { + std::cout << "out of range" << '\n'; + } +} +``` + +Output: + +``` +"il brutto" +[json.exception.type_error.304] cannot use at() with string +out of range +``` + +Example: (3) access specified object element using string_view with bounds checking + +The example below shows how object elements can be read and written using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create JSON object + json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" using string_view + std::cout << object.at("the ugly"sv) << '\n'; + + // change element with key "the bad" using string_view + object.at("the bad"sv) = "il cattivo"; + + // output changed array + std::cout << object << '\n'; + + // exception type_error.304 + try + { + // use at() with string_view on a non-object type + json str = "I am a string"; + str.at("the good"sv) = "Another string"; + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to write at a nonexisting key using string_view + object.at("the fast"sv) = "il rapido"; + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +"il brutto" +{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"} +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.403] key 'the fast' not found +``` + +Example: (3) access specified object element using string_view with bounds checking + +The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create JSON object + const json object = + { + {"the good", "il buono"}, + {"the bad", "il cattivo"}, + {"the ugly", "il brutto"} + }; + + // output element with key "the ugly" using string_view + std::cout << object.at("the ugly"sv) << '\n'; + + // exception type_error.304 + try + { + // use at() with string_view on a non-object type + const json str = "I am a string"; + std::cout << str.at("the good"sv) << '\n'; + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } + + // exception out_of_range.401 + try + { + // try to read from a nonexisting key using string_view + std::cout << object.at("the fast"sv) << '\n'; + } + catch (const json::out_of_range& e) + { + std::cout << "out of range" << '\n'; + } +} +``` + +Output: + +``` +"il brutto" +[json.exception.type_error.304] cannot use at() with string +out of range +``` + +Example: (4) access specified element via JSON Pointer + +The example below shows how object elements can be read and written using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j.at("/number"_json_pointer) << '\n'; + // output element with JSON pointer "/string" + std::cout << j.at("/string"_json_pointer) << '\n'; + // output element with JSON pointer "/array" + std::cout << j.at("/array"_json_pointer) << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j.at("/array/1"_json_pointer) << '\n'; + + // writing access + + // change the string + j.at("/string"_json_pointer) = "bar"; + // output the changed string + std::cout << j["string"] << '\n'; + + // change an array element + j.at("/array/1"_json_pointer) = 21; + // output the changed array + std::cout << j["array"] << '\n'; + + // out_of_range.106 + try + { + // try to use an array index with leading '0' + json::reference ref = j.at("/array/01"_json_pointer); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.109 + try + { + // try to use an array index that is not a number + json::reference ref = j.at("/array/one"_json_pointer); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.401 + try + { + // try to use an invalid array index + json::reference ref = j.at("/array/4"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.402 + try + { + // try to use the array index '-' + json::reference ref = j.at("/array/-"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.403 + try + { + // try to use a JSON pointer to a nonexistent object key + json::const_reference ref = j.at("/foo"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.404 + try + { + // try to use a JSON pointer that cannot be resolved + json::reference ref = j.at("/number/foo"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +1 +"foo" +[1,2] +2 +"bar" +[1,21] +[json.exception.parse_error.106] parse error: array index '01' must not begin with '0' +[json.exception.parse_error.109] parse error: array index 'one' is not a number +[json.exception.out_of_range.401] array index 4 is out of range +[json.exception.out_of_range.402] array index '-' (2) is out of range +[json.exception.out_of_range.403] key 'foo' not found +[json.exception.out_of_range.404] unresolved reference token 'foo' +``` + +Example: (4) access specified element via JSON Pointer + +The example below shows how object elements can be read using `at()`. It also demonstrates the different exceptions that can be thrown. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + const json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j.at("/number"_json_pointer) << '\n'; + // output element with JSON pointer "/string" + std::cout << j.at("/string"_json_pointer) << '\n'; + // output element with JSON pointer "/array" + std::cout << j.at("/array"_json_pointer) << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j.at("/array/1"_json_pointer) << '\n'; + + // out_of_range.109 + try + { + // try to use an array index that is not a number + json::const_reference ref = j.at("/array/one"_json_pointer); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.401 + try + { + // try to use an invalid array index + json::const_reference ref = j.at("/array/4"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.402 + try + { + // try to use the array index '-' + json::const_reference ref = j.at("/array/-"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.403 + try + { + // try to use a JSON pointer to a nonexistent object key + json::const_reference ref = j.at("/foo"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } + + // out_of_range.404 + try + { + // try to use a JSON pointer that cannot be resolved + json::const_reference ref = j.at("/number/foo"_json_pointer); + } + catch (const json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +1 +"foo" +[1,2] +2 +[json.exception.parse_error.109] parse error: array index 'one' is not a number +[json.exception.out_of_range.401] array index 4 is out of range +[json.exception.out_of_range.402] array index '-' (2) is out of range +[json.exception.out_of_range.403] key 'foo' not found +[json.exception.out_of_range.404] unresolved reference token 'foo' +``` + +## See also + +- documentation on [checked access](https://json.nlohmann.me/features/element_access/checked_access/index.md) +- [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) for unchecked access by reference +- [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) for access with default value + +## Version history + +1. Added in version 1.0.0. +1. Added in version 1.0.0. +1. Added in version 3.11.0. +1. Added in version 2.0.0. diff --git a/api/basic_json/back.md b/api/basic_json/back.md new file mode 100644 index 000000000..b717e16e0 --- /dev/null +++ b/api/basic_json/back.md @@ -0,0 +1,65 @@ +# nlohmann::basic_json::back + +```cpp +reference back(); + +const_reference back() const; +``` + +Returns a reference to the last element in the container. For a JSON container `c`, the expression `c.back()` is +equivalent to + +```cpp +auto tmp = c.end(); +--tmp; +return *tmp; +``` + +## Return value + +In the case of a structured type (array or object), a reference to the last element is returned. In the case of number, +string, boolean, or binary values, a reference to the value is returned. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +If the JSON value is `#!json null`, exception +[`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) is thrown. + +## Complexity + +Constant. + +## Notes + +!!! info "Precondition" + + The array or object must not be empty. Calling `back` on an empty array or object yields undefined behavior. + +## Examples + +??? example + + The following code shows an example for `back()`. + + ```cpp + --8<-- "examples/back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/back.output" + ``` + +## See also + +- [front](front.md) to access the first element + +## Version history + +- Added in version 1.0.0. +- Adjusted code to return reference to binary values in version 3.8.0. diff --git a/api/basic_json/back/index.html b/api/basic_json/back/index.html index 00124ec05..8bbc9a0c9 100644 --- a/api/basic_json/back/index.html +++ b/api/basic_json/back/index.html @@ -49,4 +49,4 @@ 16 "Hello, world" [json.exception.invalid_iterator.214] cannot get value -

See also

  • front to access the first element

Version history

  • Added in version 1.0.0.
  • Adjusted code to return reference to binary values in version 3.8.0.
\ No newline at end of file +

See also

  • front to access the first element

Version history

  • Added in version 1.0.0.
  • Adjusted code to return reference to binary values in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/back/index.md b/api/basic_json/back/index.md new file mode 100644 index 000000000..e0c7ac571 --- /dev/null +++ b/api/basic_json/back/index.md @@ -0,0 +1,105 @@ +# nlohmann::basic_json::back + +``` +reference back(); + +const_reference back() const; +``` + +Returns a reference to the last element in the container. For a JSON container `c`, the expression `c.back()` is equivalent to + +``` +auto tmp = c.end(); +--tmp; +return *tmp; +``` + +## Return value + +In the case of a structured type (array or object), a reference to the last element is returned. In the case of number, string, boolean, or binary values, a reference to the value is returned. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +If the JSON value is `null`, exception [`invalid_iterator.214`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator214) is thrown. + +## Complexity + +Constant. + +## Notes + +Precondition + +The array or object must not be empty. Calling `back` on an empty array or object yields undefined behavior. + +## Examples + +Example + +The following code shows an example for `back()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call back() + std::cout << j_boolean.back() << '\n'; + std::cout << j_number_integer.back() << '\n'; + std::cout << j_number_float.back() << '\n'; + std::cout << j_object.back() << '\n'; + //std::cout << j_object_empty.back() << '\n'; // undefined behavior + std::cout << j_array.back() << '\n'; + //std::cout << j_array_empty.back() << '\n'; // undefined behavior + std::cout << j_string.back() << '\n'; + + // back() called on a null value + try + { + json j_null; + j_null.back(); + } + catch (const json::invalid_iterator& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +true +17 +23.42 +2 +16 +"Hello, world" +[json.exception.invalid_iterator.214] cannot get value +``` + +## See also + +- [front](https://json.nlohmann.me/api/basic_json/front/index.md) to access the first element + +## Version history + +- Added in version 1.0.0. +- Adjusted code to return reference to binary values in version 3.8.0. diff --git a/api/basic_json/basic_json.md b/api/basic_json/basic_json.md new file mode 100644 index 000000000..83c50007e --- /dev/null +++ b/api/basic_json/basic_json.md @@ -0,0 +1,402 @@ +# nlohmann::basic_json::basic_json + +```cpp +// (1) +basic_json(const value_t v); + +// (2) +basic_json(std::nullptr_t = nullptr) noexcept; + +// (3) +template +basic_json(CompatibleType&& val) noexcept(noexcept( + JSONSerializer::to_json(std::declval(), + std::forward(val)))); + +// (4) +template +basic_json(const BasicJsonType& val); + +// (5) +basic_json(initializer_list_t init, + bool type_deduction = true, + value_t manual_type = value_t::array); + +// (6) +basic_json(size_type cnt, const basic_json& val); + +// (7) +basic_json(iterator first, iterator last); +basic_json(const_iterator first, const_iterator last); + +// (8) +basic_json(const basic_json& other); + +// (9) +basic_json(basic_json&& other) noexcept; +``` + +1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends + on the type: + + | Value type | initial value | + |------------|----------------| + | null | `#!json null` | + | boolean | `#!json false` | + | string | `#!json ""` | + | number | `#!json 0` | + | object | `#!json {}` | + | array | `#!json []` | + | binary | empty array | + + The postcondition of this constructor can be restored by calling [`clear()`](clear.md). + +2. Create a `#!json null` JSON value. It either takes a null pointer as parameter (explicitly creating `#!json null`) + or no parameter (implicitly creating `#!json null`). The passed null pointer itself is not read -- it is only used to + choose the right constructor. + +3. This is a "catch all" constructor for all compatible JSON types; that is, types for which a `to_json()` method + exists. The constructor forwards the parameter `val` to that method (to `json_serializer::to_json` method with + `U = uncvref_t`, to be exact). + + Template type `CompatibleType` includes, but is not limited to, the following types: + + - **arrays**: [`array_t`](array_t.md) and all kinds of compatible containers such as `std::vector`, `std::deque`, + `std::list`, `std::forward_list`, `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, `std::multiset`, + and `std::unordered_multiset` with a `value_type` from which a `basic_json` value can be constructed. + - **objects**: [`object_t`](object_t.md) and all kinds of compatible associative containers such as `std::map`, + `std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with a `key_type` compatible to `string_t` + and a `value_type` from which a `basic_json` value can be constructed. + - **strings**: `string_t`, string literals, and all compatible string containers can be used. + - **numbers**: [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md), + [`number_float_t`](number_float_t.md), and all convertible number types such as `int`, `size_t`, `int64_t`, `float` + or `double` can be used. + - **boolean**: `boolean_t` / `bool` can be used. + - **binary**: `binary_t` / `std::vector` may be used; unfortunately because string literals cannot be + distinguished from binary character arrays by the C++ type system, all types compatible with `const char*` will be + directed to the string constructor instead. This is both for backwards compatibility and due to the fact that a + binary type is not a standard JSON type. + + See the examples below. + +4. This is a constructor for existing `basic_json` types. It does not hijack copy/move constructors, since the parameter + has different template arguments than the current ones. + + The constructor tries to convert the internal `m_value` of the parameter. + +5. Creates a JSON value of type array or object from the passed initializer list `init`. In case `type_deduction` is + `#!cpp true` (default), the type of the JSON value to be created is deducted from the initializer list `init` + according to the following rules: + + 1. If the list is empty, an empty JSON object value `{}` is created. + 2. If the list consists of pairs whose first element is a string, a JSON object value is created where the first + elements of the pairs are treated as keys and the second elements are as values. + 3. In all other cases, an array is created. + + The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows: + + 1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object. + 2. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be + of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an + object. + 3. In all other cases, the initializer list could not be interpreted as a JSON object type, so interpreting it as a + JSON array type is safe. + + With the rules described above, the following JSON values cannot be expressed by an initializer list: + + - the empty array (`#!json []`): use `array(initializer_list_t)` with an empty initializer list in this case + - arrays whose elements satisfy rule 2: use `array(initializer_list_t)` with the same initializer list in this case + + Function [`array()`](array.md) and [`object()`](object.md) force array and object creation from initializer lists, + respectively. + +6. Constructs a JSON array value by creating `cnt` copies of a passed value. In case `cnt` is `0`, an empty array is + created. + +7. Constructs the JSON value with the contents of the range `[first, last)`. The semantics depend on the different + types a JSON value can have: + + - In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206) + is thrown. + - In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be + `end()`. In this case, the value is copied. Otherwise, + [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown. + - In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or + `std::map`; that is, a JSON array or object is constructed from the values in the range. + +8. Creates a copy of a given JSON value. + +9. Move constructor. Constructs a JSON value with the contents of the given value `other` using move semantics. It + "steals" the resources from `other` and leaves it as JSON `#!json null` value. + +## Template parameters + +`CompatibleType` +: a type such that: + + - `CompatibleType` is not derived from `std::istream`, + - `CompatibleType` is not `basic_json` (to avoid hijacking copy/move constructors), + - `CompatibleType` is not a different `basic_json` type (i.e. with different template arguments) + - `CompatibleType` is not a `basic_json` nested type (e.g., `json_pointer`, `iterator`, etc.) + - `json_serializer` (with `U = uncvref_t`) has a `to_json(basic_json_t&, CompatibleType&&)` + method + +`BasicJsonType`: +: a type such that: + + - `BasicJsonType` is a `basic_json` type. + - `BasicJsonType` has different template arguments than `basic_json_t`. + +`U`: +: `uncvref_t` + +## Parameters + +`v` (in) +: the type of the value to create + +`val` (in) +: the value to be forwarded to the respective constructor + +`init` (in) +: initializer list with JSON values + +`type_deduction` (in) +: internal parameter; when set to `#!cpp true`, the type of the JSON value is deducted from the initializer list + `init`; when set to `#!cpp false`, the type provided via `manual_type` is forced. This mode is used by the functions + `array(initializer_list_t)` and `object(initializer_list_t)`. + +`manual_type` (in) +: internal parameter; when `type_deduction` is set to `#!cpp false`, the created JSON value will use the provided type + (only `value_t::array` and `value_t::object` are valid); when `type_deduction` is set to `#!cpp true`, this + parameter has no effect + +`cnt` (in) +: the number of JSON copies of `val` to create + +`first` (in) +: the beginning of the range to copy from (included) + +`last` (in) +: the end of the range to copy from (excluded) + +`other` (in) +: the JSON value to copy/move + +## Exception safety + +1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +2. No-throw guarantee: this constructor never throws exceptions. +3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no + `to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any + JSON value. +4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no + `to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any + JSON value. +5. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +6. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +7. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +8. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +9. No-throw guarantee: this constructor never throws exceptions. + +## Exceptions + +1. (none) +2. The function does not throw exceptions. +3. (none) +4. (none) +5. The function can throw the following exceptions: + - Throws [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `type_deduction` is + `#!cpp false`, `manual_type` is `value_t::object`, but `init` contains an element which is not a pair whose first + element is a string. In this case, the constructor could not create an object. If `type_deduction` would have been + `#!cpp true`, an array would have been created. See `object(initializer_list_t)` for an example. +6. (none) +7. The function can throw the following exceptions: + - Throws [`invalid_iterator.201`](../../home/exceptions.md#jsonexceptioninvalid_iterator201) if iterators `first` + and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range + `[first, last)` is undefined. + - Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first` + and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first + element anymore. In this case, the range `[first, last)` is undefined. See the example code below. + - Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first` + and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined. +8. (none) +9. The function does not throw exceptions. + +## Complexity + +1. Constant. +2. Constant. +3. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()` + method. +4. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()` + method. +5. Linear in the size of the initializer list `init`. +6. Linear in `cnt`. +7. Linear in distance between `first` and `last`. +8. Linear in the size of `other`. +9. Constant. + +## Notes + +- Overload 5: + + !!! note "Empty initializer list" + + When used without parentheses around an empty initializer list, `basic_json()` is called instead of this + function, yielding the JSON `#!json null` value. + +- Overload 7: + + !!! info "Preconditions" + + - Iterators `first` and `last` must be initialized. **This precondition is enforced with a + [runtime assertion](../../features/assertions.md). + - Range `[first, last)` is valid. Usually, this precondition cannot be checked efficiently. Only certain edge + cases are detected; see the description of the exceptions above. A violation of this precondition yields + undefined behavior. + + !!! danger "Runtime assertion" + + A precondition is enforced with a [runtime assertion](../../features/assertions.md). + +- Overload 8: + + !!! info "Postcondition" + + `#!cpp *this == other` + +- Overload 9: + + !!! info "Postconditions" + + - `#!cpp `*this` has the same value as `other` before the call. + - `other` is a JSON `#!json null` value + +## Examples + +??? example "Example: (1) create an empty value with a given type" + + The following code shows the constructor for different `value_t` values. + + ```cpp + --8<-- "examples/basic_json__value_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__value_t.output" + ``` + +??? example "Example: (2) create a `#!json null` object" + + The following code shows the constructor with and without a null pointer parameter. + + ```cpp + --8<-- "examples/basic_json__nullptr_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__nullptr_t.output" + ``` + +??? example "Example: (3) create a JSON value from compatible types" + + The following code shows the constructor with several compatible types. + + ```cpp + --8<-- "examples/basic_json__CompatibleType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__CompatibleType.output" + ``` + + Note the output is platform-dependent. + +??? example "Example: (5) create a container (array or object) from an initializer list" + + The example below shows how JSON values are created from initializer lists. + + ```cpp + --8<-- "examples/basic_json__list_init_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__list_init_t.output" + ``` + +??? example "Example: (6) construct an array with count copies of a given value" + + The following code shows examples for creating arrays with several copies of a given value. + + ```cpp + --8<-- "examples/basic_json__size_type_basic_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__size_type_basic_json.output" + ``` + +??? example "Example: (7) construct a JSON container given an iterator range" + + The example below shows several ways to create JSON values by specifying a subrange with iterators. + + ```cpp + --8<-- "examples/basic_json__InputIt_InputIt.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__InputIt_InputIt.output" + ``` + +??? example "Example: (8) copy constructor" + + The following code shows an example for the copy constructor. + + ```cpp + --8<-- "examples/basic_json__basic_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__basic_json.output" + ``` + +??? example "Example: (9) move constructor" + + The code below shows the move constructor explicitly called via `std::move`. + + ```cpp + --8<-- "examples/basic_json__moveconstructor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__moveconstructor.output" + ``` + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +3. Since version 2.1.0. +4. Since version 3.2.0. +5. Since version 1.0.0. +6. Since version 1.0.0. +7. Since version 1.0.0. +8. Since version 1.0.0. +9. Since version 1.0.0. diff --git a/api/basic_json/basic_json/index.html b/api/basic_json/basic_json/index.html index cc3ca1e70..1f7cb65d5 100644 --- a/api/basic_json/basic_json/index.html +++ b/api/basic_json/basic_json/index.html @@ -455,4 +455,4 @@ }

Output:

null
 23
-

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.1.0.
  4. Since version 3.2.0.
  5. Since version 1.0.0.
  6. Since version 1.0.0.
  7. Since version 1.0.0.
  8. Since version 1.0.0.
  9. Since version 1.0.0.
\ No newline at end of file +

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.1.0.
  4. Since version 3.2.0.
  5. Since version 1.0.0.
  6. Since version 1.0.0.
  7. Since version 1.0.0.
  8. Since version 1.0.0.
  9. Since version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/basic_json/index.md b/api/basic_json/basic_json/index.md new file mode 100644 index 000000000..af2607996 --- /dev/null +++ b/api/basic_json/basic_json/index.md @@ -0,0 +1,751 @@ +# nlohmann::basic_json::basic_json + +``` +// (1) +basic_json(const value_t v); + +// (2) +basic_json(std::nullptr_t = nullptr) noexcept; + +// (3) +template +basic_json(CompatibleType&& val) noexcept(noexcept( + JSONSerializer::to_json(std::declval(), + std::forward(val)))); + +// (4) +template +basic_json(const BasicJsonType& val); + +// (5) +basic_json(initializer_list_t init, + bool type_deduction = true, + value_t manual_type = value_t::array); + +// (6) +basic_json(size_type cnt, const basic_json& val); + +// (7) +basic_json(iterator first, iterator last); +basic_json(const_iterator first, const_iterator last); + +// (8) +basic_json(const basic_json& other); + +// (9) +basic_json(basic_json&& other) noexcept; +``` + +1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends on the type: + + | Value type | initial value | + | ---------- | ------------- | + | null | `null` | + | boolean | `false` | + | string | `""` | + | number | `0` | + | object | `{}` | + | array | `[]` | + | binary | empty array | + + The postcondition of this constructor can be restored by calling [`clear()`](https://json.nlohmann.me/api/basic_json/clear/index.md). + +1. Create a `null` JSON value. It either takes a null pointer as parameter (explicitly creating `null`) or no parameter (implicitly creating `null`). The passed null pointer itself is not read -- it is only used to choose the right constructor. + +1. This is a "catch all" constructor for all compatible JSON types; that is, types for which a `to_json()` method exists. The constructor forwards the parameter `val` to that method (to `json_serializer::to_json` method with `U = uncvref_t`, to be exact). + + Template type `CompatibleType` includes, but is not limited to, the following types: + + - **arrays**: [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md) and all kinds of compatible containers such as `std::vector`, `std::deque`, `std::list`, `std::forward_list`, `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, `std::multiset`, and `std::unordered_multiset` with a `value_type` from which a `basic_json` value can be constructed. + - **objects**: [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md) and all kinds of compatible associative containers such as `std::map`, `std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with a `key_type` compatible to `string_t` and a `value_type` from which a `basic_json` value can be constructed. + - **strings**: `string_t`, string literals, and all compatible string containers can be used. + - **numbers**: [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md), [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md), [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md), and all convertible number types such as `int`, `size_t`, `int64_t`, `float` or `double` can be used. + - **boolean**: `boolean_t` / `bool` can be used. + - **binary**: `binary_t` / `std::vector` may be used; unfortunately because string literals cannot be distinguished from binary character arrays by the C++ type system, all types compatible with `const char*` will be directed to the string constructor instead. This is both for backwards compatibility and due to the fact that a binary type is not a standard JSON type. + + See the examples below. + +1. This is a constructor for existing `basic_json` types. It does not hijack copy/move constructors, since the parameter has different template arguments than the current ones. + + The constructor tries to convert the internal `m_value` of the parameter. + +1. Creates a JSON value of type array or object from the passed initializer list `init`. In case `type_deduction` is `true` (default), the type of the JSON value to be created is deducted from the initializer list `init` according to the following rules: + + 1. If the list is empty, an empty JSON object value `{}` is created. + 1. If the list consists of pairs whose first element is a string, a JSON object value is created where the first elements of the pairs are treated as keys and the second elements are as values. + 1. In all other cases, an array is created. + + The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows: + + 1. The empty initializer list is written as `{}` which is exactly an empty JSON object. + 1. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an object. + 1. In all other cases, the initializer list could not be interpreted as a JSON object type, so interpreting it as a JSON array type is safe. + + With the rules described above, the following JSON values cannot be expressed by an initializer list: + + - the empty array (`[]`): use `array(initializer_list_t)` with an empty initializer list in this case + - arrays whose elements satisfy rule 2: use `array(initializer_list_t)` with the same initializer list in this case + + Function [`array()`](https://json.nlohmann.me/api/basic_json/array/index.md) and [`object()`](https://json.nlohmann.me/api/basic_json/object/index.md) force array and object creation from initializer lists, respectively. + +1. Constructs a JSON array value by creating `cnt` copies of a passed value. In case `cnt` is `0`, an empty array is created. + +1. Constructs the JSON value with the contents of the range `[first, last)`. The semantics depend on the different types a JSON value can have: + + - In case of a `null` type, [invalid_iterator.206](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator206) is thrown. + - In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be `end()`. In this case, the value is copied. Otherwise, [`invalid_iterator.204`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator204) is thrown. + - In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or `std::map`; that is, a JSON array or object is constructed from the values in the range. + +1. Creates a copy of a given JSON value. + +1. Move constructor. Constructs a JSON value with the contents of the given value `other` using move semantics. It "steals" the resources from `other` and leaves it as JSON `null` value. + +## Template parameters + +`CompatibleType` : a type such that: + +``` +- `CompatibleType` is not derived from `std::istream`, +- `CompatibleType` is not `basic_json` (to avoid hijacking copy/move constructors), +- `CompatibleType` is not a different `basic_json` type (i.e. with different template arguments) +- `CompatibleType` is not a `basic_json` nested type (e.g., `json_pointer`, `iterator`, etc.) +- `json_serializer` (with `U = uncvref_t`) has a `to_json(basic_json_t&, CompatibleType&&)` + method +``` + +`BasicJsonType`: : a type such that: + +``` +- `BasicJsonType` is a `basic_json` type. +- `BasicJsonType` has different template arguments than `basic_json_t`. +``` + +`U`: : `uncvref_t` + +## Parameters + +`v` (in) : the type of the value to create + +`val` (in) : the value to be forwarded to the respective constructor + +`init` (in) : initializer list with JSON values + +`type_deduction` (in) : internal parameter; when set to `true`, the type of the JSON value is deducted from the initializer list `init`; when set to `false`, the type provided via `manual_type` is forced. This mode is used by the functions `array(initializer_list_t)` and `object(initializer_list_t)`. + +`manual_type` (in) : internal parameter; when `type_deduction` is set to `false`, the created JSON value will use the provided type (only `value_t::array` and `value_t::object` are valid); when `type_deduction` is set to `true`, this parameter has no effect + +`cnt` (in) : the number of JSON copies of `val` to create + +`first` (in) : the beginning of the range to copy from (included) + +`last` (in) : the end of the range to copy from (excluded) + +`other` (in) : the JSON value to copy/move + +## Exception safety + +1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +1. No-throw guarantee: this constructor never throws exceptions. +1. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no `to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. +1. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no `to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. +1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. +1. No-throw guarantee: this constructor never throws exceptions. + +## Exceptions + +1. (none) +1. The function does not throw exceptions. +1. (none) +1. (none) +1. The function can throw the following exceptions: + - Throws [`type_error.301`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error301) if `type_deduction` is `false`, `manual_type` is `value_t::object`, but `init` contains an element which is not a pair whose first element is a string. In this case, the constructor could not create an object. If `type_deduction` would have been `true`, an array would have been created. See `object(initializer_list_t)` for an example. +1. (none) +1. The function can throw the following exceptions: + - Throws [`invalid_iterator.201`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator201) if iterators `first` and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range `[first, last)` is undefined. + - Throws [`invalid_iterator.204`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator204) if iterators `first` and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first element anymore. In this case, the range `[first, last)` is undefined. See the example code below. + - Throws [`invalid_iterator.206`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator206) if iterators `first` and `last` belong to a `null` value. In this case, the range `[first, last)` is undefined. +1. (none) +1. The function does not throw exceptions. + +## Complexity + +1. Constant. +1. Constant. +1. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()` method. +1. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()` method. +1. Linear in the size of the initializer list `init`. +1. Linear in `cnt`. +1. Linear in distance between `first` and `last`. +1. Linear in the size of `other`. +1. Constant. + +## Notes + +- Overload 5: + + Empty initializer list + + When used without parentheses around an empty initializer list, `basic_json()` is called instead of this function, yielding the JSON `null` value. + +- Overload 7: + + Preconditions + + - Iterators `first` and `last` must be initialized. \*\*This precondition is enforced with a [runtime assertion](https://json.nlohmann.me/features/assertions/index.md). + - Range `[first, last)` is valid. Usually, this precondition cannot be checked efficiently. Only certain edge cases are detected; see the description of the exceptions above. A violation of this precondition yields undefined behavior. + + Runtime assertion + + A precondition is enforced with a [runtime assertion](https://json.nlohmann.me/features/assertions/index.md). + +- Overload 8: + + Postcondition + + `*this == other` + +- Overload 9: + + Postconditions + + - `` `*this `` has the same value as `other` before the call. + - `other` is a JSON `null` value + +## Examples + +Example: (1) create an empty value with a given type + +The following code shows the constructor for different `value_t` values. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create the different JSON values with default values + json j_null(json::value_t::null); + json j_boolean(json::value_t::boolean); + json j_number_integer(json::value_t::number_integer); + json j_number_float(json::value_t::number_float); + json j_object(json::value_t::object); + json j_array(json::value_t::array); + json j_string(json::value_t::string); + + // serialize the JSON values + std::cout << j_null << '\n'; + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} +``` + +Output: + +``` +null +false +0 +0.0 +{} +[] +"" +``` + +Example: (2) create a `null` object + +The following code shows the constructor with and without a null pointer parameter. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // implicitly create a JSON null value + json j1; + + // explicitly create a JSON null value + json j2(nullptr); + + // serialize the JSON null value + std::cout << j1 << '\n' << j2 << '\n'; +} +``` + +Output: + +``` +null +null +``` + +Example: (3) create a JSON value from compatible types + +The following code shows the constructor with several compatible types. + +``` +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // ============ + // object types + // ============ + + // create an object from an object_t value + json::object_t object_value = { {"one", 1}, {"two", 2} }; + json j_object_t(object_value); + + // create an object from std::map + std::map c_map + { + {"one", 1}, {"two", 2}, {"three", 3} + }; + json j_map(c_map); + + // create an object from std::unordered_map + std::unordered_map c_umap + { + {"one", 1.2}, {"two", 2.3}, {"three", 3.4} + }; + json j_umap(c_umap); + + // create an object from std::multimap + std::multimap c_mmap + { + {"one", true}, {"two", true}, {"three", false}, {"three", true} + }; + json j_mmap(c_mmap); // only one entry for key "three" is used + + // create an object from std::unordered_multimap + std::unordered_multimap c_ummap + { + {"one", true}, {"two", true}, {"three", false}, {"three", true} + }; + json j_ummap(c_ummap); // only one entry for key "three" is used + + // serialize the JSON objects + std::cout << j_object_t << '\n'; + std::cout << j_map << '\n'; + std::cout << j_umap << '\n'; + std::cout << j_mmap << '\n'; + std::cout << j_ummap << "\n\n"; + + // =========== + // array types + // =========== + + // create an array from an array_t value + json::array_t array_value = {"one", "two", 3, 4.5, false}; + json j_array_t(array_value); + + // create an array from std::vector + std::vector c_vector {1, 2, 3, 4}; + json j_vec(c_vector); + + // create an array from std::valarray + std::valarray c_valarray {10, 9, 8, 7}; + json j_valarray(c_valarray); + + // create an array from std::deque + std::deque c_deque {1.2, 2.3, 3.4, 5.6}; + json j_deque(c_deque); + + // create an array from std::list + std::list c_list {true, true, false, true}; + json j_list(c_list); + + // create an array from std::forward_list + std::forward_list c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; + json j_flist(c_flist); + + // create an array from std::array + std::array c_array {{1, 2, 3, 4}}; + json j_array(c_array); + + // create an array from std::set + std::set c_set {"one", "two", "three", "four", "one"}; + json j_set(c_set); // only one entry for "one" is used + + // create an array from std::unordered_set + std::unordered_set c_uset {"one", "two", "three", "four", "one"}; + json j_uset(c_uset); // only one entry for "one" is used + + // create an array from std::multiset + std::multiset c_mset {"one", "two", "one", "four"}; + json j_mset(c_mset); // both entries for "one" are used + + // create an array from std::unordered_multiset + std::unordered_multiset c_umset {"one", "two", "one", "four"}; + json j_umset(c_umset); // both entries for "one" are used + + // serialize the JSON arrays + std::cout << j_array_t << '\n'; + std::cout << j_vec << '\n'; + std::cout << j_valarray << '\n'; + std::cout << j_deque << '\n'; + std::cout << j_list << '\n'; + std::cout << j_flist << '\n'; + std::cout << j_array << '\n'; + std::cout << j_set << '\n'; + std::cout << j_uset << '\n'; + std::cout << j_mset << '\n'; + std::cout << j_umset << "\n\n"; + + // ============ + // string types + // ============ + + // create string from a string_t value + json::string_t string_value = "The quick brown fox jumps over the lazy dog."; + json j_string_t(string_value); + + // create a JSON string directly from a string literal + json j_string_literal("The quick brown fox jumps over the lazy dog."); + + // create string from std::string + std::string s_stdstring = "The quick brown fox jumps over the lazy dog."; + json j_stdstring(s_stdstring); + + // serialize the JSON strings + std::cout << j_string_t << '\n'; + std::cout << j_string_literal << '\n'; + std::cout << j_stdstring << "\n\n"; + + // ============ + // number types + // ============ + + // create a JSON number from number_integer_t + json::number_integer_t value_integer_t = -42; + json j_integer_t(value_integer_t); + + // create a JSON number from number_unsigned_t + json::number_integer_t value_unsigned_t = 17; + json j_unsigned_t(value_unsigned_t); + + // create a JSON number from an anonymous enum + enum { enum_value = 17 }; + json j_enum(enum_value); + + // create values of different integer types + short n_short = 42; + int n_int = -23; + long n_long = 1024; + int_least32_t n_int_least32_t = -17; + uint8_t n_uint8_t = 8; + + // create (integer) JSON numbers + json j_short(n_short); + json j_int(n_int); + json j_long(n_long); + json j_int_least32_t(n_int_least32_t); + json j_uint8_t(n_uint8_t); + + // create values of different floating-point types + json::number_float_t v_ok = 3.141592653589793; + json::number_float_t v_nan = NAN; + json::number_float_t v_infinity = INFINITY; + + // create values of different floating-point types + float n_float = 42.23; + float n_float_nan = 1.0f / 0.0f; + double n_double = 23.42; + + // create (floating point) JSON numbers + json j_ok(v_ok); + json j_nan(v_nan); + json j_infinity(v_infinity); + json j_float(n_float); + json j_float_nan(n_float_nan); + json j_double(n_double); + + // serialize the JSON numbers + std::cout << j_integer_t << '\n'; + std::cout << j_unsigned_t << '\n'; + std::cout << j_enum << '\n'; + std::cout << j_short << '\n'; + std::cout << j_int << '\n'; + std::cout << j_long << '\n'; + std::cout << j_int_least32_t << '\n'; + std::cout << j_uint8_t << '\n'; + std::cout << j_ok << '\n'; + std::cout << j_nan << '\n'; + std::cout << j_infinity << '\n'; + std::cout << j_float << '\n'; + std::cout << j_float_nan << '\n'; + std::cout << j_double << "\n\n"; + + // ============= + // boolean types + // ============= + + // create boolean values + json j_truth = true; + json j_falsity = false; + + // serialize the JSON booleans + std::cout << j_truth << '\n'; + std::cout << j_falsity << '\n'; +} +``` + +Output: + +``` +{"one":1,"two":2} +{"one":1,"three":3,"two":2} +{"one":1.2,"three":3.4,"two":2.3} +{"one":true,"three":false,"two":true} +{"one":true,"three":false,"two":true} + +["one","two",3,4.5,false] +[1,2,3,4] +[10,9,8,7] +[1.2,2.3,3.4,5.6] +[true,true,false,true] +[12345678909876,23456789098765,34567890987654,45678909876543] +[1,2,3,4] +["four","one","three","two"] +["four","three","two","one"] +["four","one","one","two"] +["four","two","one","one"] + +"The quick brown fox jumps over the lazy dog." +"The quick brown fox jumps over the lazy dog." +"The quick brown fox jumps over the lazy dog." + +-42 +17 +17 +42 +-23 +1024 +-17 +8 +3.141592653589793 +null +null +42.22999954223633 +null +23.42 + +true +false +``` + +Note the output is platform-dependent. + +Example: (5) create a container (array or object) from an initializer list + +The example below shows how JSON values are created from initializer lists. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_empty_init_list = json({}); + json j_object = { {"one", 1}, {"two", 2} }; + json j_array = {1, 2, 3, 4}; + json j_nested_object = { {"one", {1}}, {"two", {1, 2}} }; + json j_nested_array = { {{1}, "one"}, {{1, 2}, "two"} }; + + // serialize the JSON value + std::cout << j_empty_init_list << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_nested_object << '\n'; + std::cout << j_nested_array << '\n'; +} +``` + +Output: + +``` +{} +{"one":1,"two":2} +[1,2,3,4] +{"one":[1],"two":[1,2]} +[[[1],"one"],[[1,2],"two"]] +``` + +Example: (6) construct an array with count copies of a given value + +The following code shows examples for creating arrays with several copies of a given value. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array by creating copies of a JSON value + json value = "Hello"; + json array_0 = json(0, value); + json array_1 = json(1, value); + json array_5 = json(5, value); + + // serialize the JSON arrays + std::cout << array_0 << '\n'; + std::cout << array_1 << '\n'; + std::cout << array_5 << '\n'; +} +``` + +Output: + +``` +[] +["Hello"] +["Hello","Hello","Hello","Hello","Hello"] +``` + +Example: (7) construct a JSON container given an iterator range + +The example below shows several ways to create JSON values by specifying a subrange with iterators. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_array = {"alpha", "bravo", "charly", "delta", "easy"}; + json j_number = 42; + json j_object = {{"one", "eins"}, {"two", "zwei"}}; + + // create copies using iterators + json j_array_range(j_array.begin() + 1, j_array.end() - 2); + json j_number_range(j_number.begin(), j_number.end()); + json j_object_range(j_object.begin(), j_object.find("two")); + + // serialize the values + std::cout << j_array_range << '\n'; + std::cout << j_number_range << '\n'; + std::cout << j_object_range << '\n'; + + // example for an exception + try + { + json j_invalid(j_number.begin() + 1, j_number.end()); + } + catch (const json::invalid_iterator& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +["bravo","charly"] +42 +{"one":"eins"} +[json.exception.invalid_iterator.204] iterators out of range +``` + +Example: (8) copy constructor + +The following code shows an example for the copy constructor. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json j1 = {"one", "two", 3, 4.5, false}; + + // create a copy + json j2(j1); + + // serialize the JSON array + std::cout << j1 << " = " << j2 << '\n'; + std::cout << std::boolalpha << (j1 == j2) << '\n'; +} +``` + +Output: + +``` +["one","two",3,4.5,false] = ["one","two",3,4.5,false] +true +``` + +Example: (9) move constructor + +The code below shows the move constructor explicitly called via `std::move`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json a = 23; + + // move contents of a to b + json b(std::move(a)); + + // serialize the JSON arrays + std::cout << a << '\n'; + std::cout << b << '\n'; +} +``` + +Output: + +``` +null +23 +``` + +## Version history + +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 2.1.0. +1. Since version 3.2.0. +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 1.0.0. diff --git a/api/basic_json/begin.md b/api/basic_json/begin.md new file mode 100644 index 000000000..ef623a5ff --- /dev/null +++ b/api/basic_json/begin.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::begin + +```cpp +iterator begin() noexcept; +const_iterator begin() const noexcept; +``` + +Returns an iterator to the first element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `begin()`. + + ```cpp + --8<-- "examples/begin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/begin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/begin/index.html b/api/basic_json/begin/index.html index ae6cbb0f0..c6d074c66 100644 --- a/api/basic_json/begin/index.html +++ b/api/basic_json/begin/index.html @@ -17,4 +17,4 @@ std::cout << *it << '\n'; }

Output:

1
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/begin/index.md b/api/basic_json/begin/index.md new file mode 100644 index 000000000..507f61464 --- /dev/null +++ b/api/basic_json/begin/index.md @@ -0,0 +1,55 @@ +# nlohmann::basic_json::begin + +``` +iterator begin() noexcept; +const_iterator begin() const noexcept; +``` + +Returns an iterator to the first element. + +## Return value + +iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `begin()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the first element + json::iterator it = array.begin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +1 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/binary.md b/api/basic_json/binary.md new file mode 100644 index 000000000..efd4347ca --- /dev/null +++ b/api/basic_json/binary.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::binary + +```cpp +// (1) +static basic_json binary(const typename binary_t::container_type& init); +static basic_json binary(typename binary_t::container_type&& init); + +// (2) +static basic_json binary(const typename binary_t::container_type& init, + std::uint8_t subtype); +static basic_json binary(typename binary_t::container_type&& init, + std::uint8_t subtype); +``` + +1. Creates a JSON binary array value from a given binary container. +2. Creates a JSON binary array value from a given binary container with subtype. + +Binary values are part of various binary formats, such as CBOR, MessagePack, and BSON. This constructor is used to +create a value for serialization to those formats. + +## Parameters + +`init` (in) +: container containing bytes to use as a binary type + +`subtype` (in) +: subtype to use in CBOR, MessagePack, and BSON + +## Return value + +JSON binary array value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of `init`; constant for `typename binary_t::container_type&& init` versions. + +## Notes + +Note, this function exists because of the difficulty in correctly specifying the correct template overload in the +standard value ctor, as both JSON arrays and JSON binary arrays are backed with some form of a `std::vector`. Because +JSON binary arrays are a non-standard extension, it was decided that it would be best to prevent automatic +initialization of a binary array type, for backwards compatibility and so it does not happen on accident. + +## Examples + +??? example + + The following code shows how to create a binary value. + + ```cpp + --8<-- "examples/binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/binary.output" + ``` + +## Version history + +- Added in version 3.8.0. diff --git a/api/basic_json/binary/index.html b/api/basic_json/binary/index.html index 66c676809..4d5e8dbaf 100644 --- a/api/basic_json/binary/index.html +++ b/api/basic_json/binary/index.html @@ -24,4 +24,4 @@ std::cout << "type: " << j.type_name() << ", subtype: " << j.get_binary().subtype() << std::endl; }

Output:

type: binary, subtype: 42
-

Version history

  • Added in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/binary/index.md b/api/basic_json/binary/index.md new file mode 100644 index 000000000..f07f8fcfd --- /dev/null +++ b/api/basic_json/binary/index.md @@ -0,0 +1,75 @@ +# nlohmann::basic_json::binary + +``` +// (1) +static basic_json binary(const typename binary_t::container_type& init); +static basic_json binary(typename binary_t::container_type&& init); + +// (2) +static basic_json binary(const typename binary_t::container_type& init, + std::uint8_t subtype); +static basic_json binary(typename binary_t::container_type&& init, + std::uint8_t subtype); +``` + +1. Creates a JSON binary array value from a given binary container. +1. Creates a JSON binary array value from a given binary container with subtype. + +Binary values are part of various binary formats, such as CBOR, MessagePack, and BSON. This constructor is used to create a value for serialization to those formats. + +## Parameters + +`init` (in) : container containing bytes to use as a binary type + +`subtype` (in) : subtype to use in CBOR, MessagePack, and BSON + +## Return value + +JSON binary array value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of `init`; constant for `typename binary_t::container_type&& init` versions. + +## Notes + +Note, this function exists because of the difficulty in correctly specifying the correct template overload in the standard value ctor, as both JSON arrays and JSON binary arrays are backed with some form of a `std::vector`. Because JSON binary arrays are a non-standard extension, it was decided that it would be best to prevent automatic initialization of a binary array type, for backwards compatibility and so it does not happen on accident. + +## Examples + +Example + +The following code shows how to create a binary value. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a binary vector + std::vector vec = {0xCA, 0xFE, 0xBA, 0xBE}; + + // create a binary JSON value with subtype 42 + json j = json::binary(vec, 42); + + // output type and subtype + std::cout << "type: " << j.type_name() << ", subtype: " << j.get_binary().subtype() << std::endl; +} +``` + +Output: + +``` +type: binary, subtype: 42 +``` + +## Version history + +- Added in version 3.8.0. diff --git a/api/basic_json/binary_t.md b/api/basic_json/binary_t.md new file mode 100644 index 000000000..902ffe732 --- /dev/null +++ b/api/basic_json/binary_t.md @@ -0,0 +1,89 @@ +# nlohmann::basic_json::binary_t + +```cpp +using binary_t = byte_container_with_subtype; +``` + +This type is a type designed to carry binary data that appears in various serialized formats, such as CBOR's Major Type +2, MessagePack's bin, and BSON's generic binary subtype. This type is NOT a part of standard JSON and exists solely for +compatibility with these binary types. As such, it is simply defined as an ordered sequence of zero or more byte values. + +Additionally, as an implementation detail, the subtype of the binary data is carried around as a `std::uint64_t`, which +is compatible with both of the binary data formats that use binary subtyping, (though the specific numbering is +incompatible with each other, and it is up to the user to translate between them). The subtype is added to `BinaryType` +via the helper type [byte_container_with_subtype](../byte_container_with_subtype/index.md). + +[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type as: +> Major type 2: a byte string. The string's length in bytes is represented following the rules for positive integers +> (major type 0). + +[MessagePack's documentation on the bin type +family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) describes this type as: +> Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array. + +[BSON's specifications](http://bsonspec.org/spec.html) describe several binary types; however, this type is intended to +represent the generic binary type which has the description: +> Generic binary subtype - This is the most commonly used binary subtype and should be the 'default' for drivers and +> tools. + +None of these impose any limitations on the internal representation other than the basic unit of storage be some type of +array whose parts are decomposable into bytes. + +The default representation of this binary format is a `#!cpp std::vector`, which is a very common way to +represent a byte array in modern C++. + +## Template parameters + +`BinaryType` +: container type to store arrays + +## Notes + +#### Default type + +The default values for `BinaryType` is `#!cpp std::vector`. + +#### Storage + +Binary Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of the +type `#!cpp binary_t*` must be dereferenced. + +#### Notes on subtypes + +- CBOR + - Binary values are represented as byte strings. Subtypes are written as tags. + +- MessagePack + - If a subtype is given and the binary array contains exactly 1, 2, 4, 8, or 16 elements, the fixext family (fixext1, + fixext2, fixext4, fixext8) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is + then added as a signed 8-bit integer. + - If no subtype is given, the bin family (bin8, bin16, bin32) is used. + +- BSON + - If a subtype is given, it is used and added as an unsigned 8-bit integer. + - If no subtype is given, the generic binary subtype 0x00 is used. + +## Examples + +??? example + + The following code shows that `binary_t` is by default, a typedef to + `#!cpp nlohmann::byte_container_with_subtype>`. + + ```cpp + --8<-- "examples/binary_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/binary_t.output" + ``` + +## See also + +- [byte_container_with_subtype](../byte_container_with_subtype/index.md) + +## Version history + +- Added in version 3.8.0. Changed the type of subtype to `std::uint64_t` in version 3.10.0. diff --git a/api/basic_json/binary_t/index.html b/api/basic_json/binary_t/index.html index 4884c7827..5382c4c89 100644 --- a/api/basic_json/binary_t/index.html +++ b/api/basic_json/binary_t/index.html @@ -10,4 +10,4 @@ std::cout << std::boolalpha << std::is_same<nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>, json::binary_t>::value << std::endl; }

Output:

true
-

See also

Version history

  • Added in version 3.8.0. Changed the type of subtype to std::uint64_t in version 3.10.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.8.0. Changed the type of subtype to std::uint64_t in version 3.10.0.
\ No newline at end of file diff --git a/api/basic_json/binary_t/index.md b/api/basic_json/binary_t/index.md new file mode 100644 index 000000000..01470cb73 --- /dev/null +++ b/api/basic_json/binary_t/index.md @@ -0,0 +1,88 @@ +# nlohmann::basic_json::binary_t + +``` +using binary_t = byte_container_with_subtype; +``` + +This type is a type designed to carry binary data that appears in various serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and BSON's generic binary subtype. This type is NOT a part of standard JSON and exists solely for compatibility with these binary types. As such, it is simply defined as an ordered sequence of zero or more byte values. + +Additionally, as an implementation detail, the subtype of the binary data is carried around as a `std::uint64_t`, which is compatible with both of the binary data formats that use binary subtyping, (though the specific numbering is incompatible with each other, and it is up to the user to translate between them). The subtype is added to `BinaryType` via the helper type [byte_container_with_subtype](https://json.nlohmann.me/api/byte_container_with_subtype/index.md). + +[CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type as: + +> Major type 2: a byte string. The string's length in bytes is represented following the rules for positive integers (major type 0). + +[MessagePack's documentation on the bin type family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) describes this type as: + +> Bin format family stores a byte array in 2, 3, or 5 bytes of extra bytes in addition to the size of the byte array. + +[BSON's specifications](http://bsonspec.org/spec.html) describe several binary types; however, this type is intended to represent the generic binary type which has the description: + +> Generic binary subtype - This is the most commonly used binary subtype and should be the 'default' for drivers and tools. + +None of these impose any limitations on the internal representation other than the basic unit of storage be some type of array whose parts are decomposable into bytes. + +The default representation of this binary format is a `std::vector`, which is a very common way to represent a byte array in modern C++. + +## Template parameters + +`BinaryType` : container type to store arrays + +## Notes + +#### Default type + +The default values for `BinaryType` is `std::vector`. + +#### Storage + +Binary Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of the type `binary_t*` must be dereferenced. + +#### Notes on subtypes + +- CBOR + + - Binary values are represented as byte strings. Subtypes are written as tags. + +- MessagePack + + - If a subtype is given and the binary array contains exactly 1, 2, 4, 8, or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8) is used. For other sizes, the ext family (ext8, ext16, ext32) is used. The subtype is then added as a signed 8-bit integer. + - If no subtype is given, the bin family (bin8, bin16, bin32) is used. + +- BSON + + - If a subtype is given, it is used and added as an unsigned 8-bit integer. + - If no subtype is given, the generic binary subtype 0x00 is used. + +## Examples + +Example + +The following code shows that `binary_t` is by default, a typedef to `nlohmann::byte_container_with_subtype>`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same>, json::binary_t>::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## See also + +- [byte_container_with_subtype](https://json.nlohmann.me/api/byte_container_with_subtype/index.md) + +## Version history + +- Added in version 3.8.0. Changed the type of subtype to `std::uint64_t` in version 3.10.0. diff --git a/api/basic_json/boolean_t.md b/api/basic_json/boolean_t.md new file mode 100644 index 000000000..c30afefdc --- /dev/null +++ b/api/basic_json/boolean_t.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::boolean_t + +```cpp +using boolean_t = BooleanType; +``` + +The type used to store JSON booleans. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two +literals `#!json true` and `#!json false`. + +To store boolean values in C++, a type is defined by the template parameter `BooleanType` which chooses the type to use. + +## Notes + +#### Default type + +With the default values for `BooleanType` (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`. + +#### Storage + +Boolean values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `boolean_t` is by default, a typedef to `#!cpp bool`. + + ```cpp + --8<-- "examples/boolean_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/boolean_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/boolean_t/index.html b/api/basic_json/boolean_t/index.html index 71145d408..5774d07c6 100644 --- a/api/basic_json/boolean_t/index.html +++ b/api/basic_json/boolean_t/index.html @@ -10,4 +10,4 @@ std::cout << std::boolalpha << std::is_same<bool, json::boolean_t>::value << std::endl; }

Output:

true
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/boolean_t/index.md b/api/basic_json/boolean_t/index.md new file mode 100644 index 000000000..30abf82f9 --- /dev/null +++ b/api/basic_json/boolean_t/index.md @@ -0,0 +1,50 @@ +# nlohmann::basic_json::boolean_t + +``` +using boolean_t = BooleanType; +``` + +The type used to store JSON booleans. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`. + +To store boolean values in C++, a type is defined by the template parameter `BooleanType` which chooses the type to use. + +## Notes + +#### Default type + +With the default values for `BooleanType` (`bool`), the default value for `boolean_t` is `bool`. + +#### Storage + +Boolean values are stored directly inside a `basic_json` type. + +## Examples + +Example + +The following code shows that `boolean_t` is by default, a typedef to `bool`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/cbegin.md b/api/basic_json/cbegin.md new file mode 100644 index 000000000..06504fee6 --- /dev/null +++ b/api/basic_json/cbegin.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::cbegin + +```cpp +const_iterator cbegin() const noexcept; +``` + +Returns an iterator to the first element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `cbegin()`. + + ```cpp + --8<-- "examples/cbegin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/cbegin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/cbegin/index.html b/api/basic_json/cbegin/index.html index 5e1e29ee2..9426abe41 100644 --- a/api/basic_json/cbegin/index.html +++ b/api/basic_json/cbegin/index.html @@ -16,4 +16,4 @@ std::cout << *it << '\n'; }

Output:

1
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/cbegin/index.md b/api/basic_json/cbegin/index.md new file mode 100644 index 000000000..cc0a20503 --- /dev/null +++ b/api/basic_json/cbegin/index.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::cbegin + +``` +const_iterator cbegin() const noexcept; +``` + +Returns an iterator to the first element. + +## Return value + +iterator to the first element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `cbegin()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + const json array = {1, 2, 3, 4, 5}; + + // get an iterator to the first element + json::const_iterator it = array.cbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +1 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/cbor_tag_handler_t.md b/api/basic_json/cbor_tag_handler_t.md new file mode 100644 index 000000000..e19c3edd9 --- /dev/null +++ b/api/basic_json/cbor_tag_handler_t.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::cbor_tag_handler_t + +```cpp +enum class cbor_tag_handler_t +{ + error, + ignore, + store +}; +``` + +This enumeration is used in the [`from_cbor`](from_cbor.md) function to choose how to treat tags: + +error +: throw a `parse_error` exception in case of a tag + +ignore +: ignore tags + +store +: store tagged values as binary container with subtype (for bytes 0xd8..0xdb) + +## Examples + +??? example + + The example below shows how the different values of the `cbor_tag_handler_t` influence the behavior of + [`from_cbor`](from_cbor.md) when reading a tagged byte string. + + ```cpp + --8<-- "examples/cbor_tag_handler_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/cbor_tag_handler_t.output" + ``` + +## Version history + +- Added in version 3.9.0. Added value `store` in 3.10.0. diff --git a/api/basic_json/cbor_tag_handler_t/index.html b/api/basic_json/cbor_tag_handler_t/index.html index f75b02bbb..af82b3a7c 100644 --- a/api/basic_json/cbor_tag_handler_t/index.html +++ b/api/basic_json/cbor_tag_handler_t/index.html @@ -35,4 +35,4 @@

Output:

[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xD8
 {"bytes":[202,254,186,190],"subtype":null}
 {"bytes":[202,254,186,190],"subtype":66}
-

Version history

  • Added in version 3.9.0. Added value store in 3.10.0.
\ No newline at end of file +

Version history

  • Added in version 3.9.0. Added value store in 3.10.0.
\ No newline at end of file diff --git a/api/basic_json/cbor_tag_handler_t/index.md b/api/basic_json/cbor_tag_handler_t/index.md new file mode 100644 index 000000000..9ff823632 --- /dev/null +++ b/api/basic_json/cbor_tag_handler_t/index.md @@ -0,0 +1,67 @@ +# nlohmann::basic_json::cbor_tag_handler_t + +``` +enum class cbor_tag_handler_t +{ + error, + ignore, + store +}; +``` + +This enumeration is used in the [`from_cbor`](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) function to choose how to treat tags: + +error : throw a `parse_error` exception in case of a tag + +ignore : ignore tags + +store : store tagged values as binary container with subtype (for bytes 0xd8..0xdb) + +## Examples + +Example + +The example below shows how the different values of the `cbor_tag_handler_t` influence the behavior of [`from_cbor`](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) when reading a tagged byte string. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // tagged byte string + std::vector vec = {{0xd8, 0x42, 0x44, 0xcA, 0xfe, 0xba, 0xbe}}; + + // cbor_tag_handler_t::error throws + try + { + auto b_throw_on_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::error); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << std::endl; + } + + // cbor_tag_handler_t::ignore ignores the tag + auto b_ignore_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::ignore); + std::cout << b_ignore_tag << std::endl; + + // cbor_tag_handler_t::store stores the tag as binary subtype + auto b_store_tag = json::from_cbor(vec, true, true, json::cbor_tag_handler_t::store); + std::cout << b_store_tag << std::endl; +} +``` + +Output: + +``` +[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xD8 +{"bytes":[202,254,186,190],"subtype":null} +{"bytes":[202,254,186,190],"subtype":66} +``` + +## Version history + +- Added in version 3.9.0. Added value `store` in 3.10.0. diff --git a/api/basic_json/cend.md b/api/basic_json/cend.md new file mode 100644 index 000000000..3f3aa949d --- /dev/null +++ b/api/basic_json/cend.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::cend + +```cpp +const_iterator cend() const noexcept; +``` + +Returns an iterator to one past the last element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator one past the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `cend()`. + + ```cpp + --8<-- "examples/cend.cpp" + ``` + + Output: + + ```json + --8<-- "examples/cend.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/cend/index.html b/api/basic_json/cend/index.html index 965d6ad5b..a331e248c 100644 --- a/api/basic_json/cend/index.html +++ b/api/basic_json/cend/index.html @@ -19,4 +19,4 @@ std::cout << *it << '\n'; }

Output:

5
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/cend/index.md b/api/basic_json/cend/index.md new file mode 100644 index 000000000..3cf321599 --- /dev/null +++ b/api/basic_json/cend/index.md @@ -0,0 +1,57 @@ +# nlohmann::basic_json::cend + +``` +const_iterator cend() const noexcept; +``` + +Returns an iterator to one past the last element. + +## Return value + +iterator one past the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `cend()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to one past the last element + json::const_iterator it = array.cend(); + + // decrement the iterator to point to the last element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +5 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/clear.md b/api/basic_json/clear.md new file mode 100644 index 000000000..427a7fc39 --- /dev/null +++ b/api/basic_json/clear.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json::clear + +```cpp +void clear() noexcept; +``` + +Clears the content of a JSON value and resets it to the default value as if [`basic_json(value_t)`](basic_json.md) would +have been called with the current value type from [`type()`](type.md): + +| Value type | initial value | +|------------|----------------------| +| null | `null` | +| boolean | `false` | +| string | `""` | +| number | `0` | +| binary | An empty byte vector | +| object | `{}` | +| array | `[]` | + +Has the same effect as calling + +```.cpp +*this = basic_json(type()); +``` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +All iterators, pointers, and references related to this container are invalidated. + +## Examples + +??? example + + The example below shows the effect of `clear()` to different + JSON types. + + ```cpp + --8<-- "examples/clear.cpp" + ``` + + Output: + + ```json + --8<-- "examples/clear.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added support for binary types in version 3.8.0. diff --git a/api/basic_json/clear/index.html b/api/basic_json/clear/index.html index 43e92a879..015c05477 100644 --- a/api/basic_json/clear/index.html +++ b/api/basic_json/clear/index.html @@ -41,4 +41,4 @@ {} [] "" -

Version history

  • Added in version 1.0.0.
  • Added support for binary types in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
  • Added support for binary types in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/clear/index.md b/api/basic_json/clear/index.md new file mode 100644 index 000000000..e727132c1 --- /dev/null +++ b/api/basic_json/clear/index.md @@ -0,0 +1,95 @@ +# nlohmann::basic_json::clear + +``` +void clear() noexcept; +``` + +Clears the content of a JSON value and resets it to the default value as if [`basic_json(value_t)`](https://json.nlohmann.me/api/basic_json/basic_json/index.md) would have been called with the current value type from [`type()`](https://json.nlohmann.me/api/basic_json/type/index.md): + +| Value type | initial value | +| ---------- | -------------------- | +| null | `null` | +| boolean | `false` | +| string | `""` | +| number | `0` | +| binary | An empty byte vector | +| object | `{}` | +| array | `[]` | + +Has the same effect as calling + +``` +*this = basic_json(type()); +``` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +All iterators, pointers, and references related to this container are invalidated. + +## Examples + +Example + +The example below shows the effect of `clear()` to different JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call clear() + j_null.clear(); + j_boolean.clear(); + j_number_integer.clear(); + j_number_float.clear(); + j_object.clear(); + j_array.clear(); + j_string.clear(); + + // serialize the cleared values() + std::cout << j_null << '\n'; + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} +``` + +Output: + +``` +null +false +0 +0.0 +{} +[] +"" +``` + +## Version history + +- Added in version 1.0.0. +- Added support for binary types in version 3.8.0. diff --git a/api/basic_json/contains.md b/api/basic_json/contains.md new file mode 100644 index 000000000..7f865f83c --- /dev/null +++ b/api/basic_json/contains.md @@ -0,0 +1,119 @@ +# nlohmann::basic_json::contains + +```cpp +// (1) +bool contains(const typename object_t::key_type& key) const; + +// (2) +template +bool contains(KeyType&& key) const; + +// (3) +bool contains(const json_pointer& ptr) const; +``` + +1. Check whether an element exists in a JSON object with a key equivalent to `key`. If the element is not found or the + JSON value is not an object, `#!cpp false` is returned. +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. +3. Check whether the given JSON pointer `ptr` can be resolved in the current JSON value. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`key` (in) +: key value to check its existence. + +`ptr` (in) +: JSON pointer to check its existence. + +## Return value + +1. `#!cpp true` if an element with specified `key` exists. If no such element with such a key is found or the JSON value + is not an object, `#!cpp false` is returned. +2. See 1. +3. `#!cpp true` if the JSON pointer can be resolved to a stored value, `#!cpp false` otherwise. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function does not throw exceptions. +2. The function does not throw exceptions. +3. The function does not throw exceptions. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +- This method always returns `#!cpp false` when executed on a JSON type that is not an object. +- This method can be executed on any JSON value type. + +!!! info "Postconditions" + + If `#!cpp j.contains(x)` returns `#!c true` for a key or JSON pointer `x`, then it is safe to call `j[x]`. + +## Examples + +??? example "Example: (1) check with key" + + The example shows how `contains()` is used. + + ```cpp + --8<-- "examples/contains__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/contains__object_t_key_type.output" + ``` + +??? example "Example: (2) check with key using string_view" + + The example shows how `contains()` is used. + + ```cpp + --8<-- "examples/contains__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/contains__keytype.c++17.output" + ``` + +??? example "Example: (3) check with JSON pointer" + + The example shows how `contains()` is used. + + ```cpp + --8<-- "examples/contains__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/contains__json_pointer.output" + ``` + +## See also + +- [find](find.md) find a value in an object +- [count](count.md) returns the number of occurrences of a key + +## Version history + +1. Added in version 3.11.0. +2. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0. +3. Added in version 3.7.0. diff --git a/api/basic_json/contains/index.html b/api/basic_json/contains/index.html index 1ef4af919..f90c7d227 100644 --- a/api/basic_json/contains/index.html +++ b/api/basic_json/contains/index.html @@ -101,4 +101,4 @@ false false false -

See also

  • find find a value in an object
  • count returns the number of occurrences of a key

Version history

  1. Added in version 3.11.0.
  2. Added in version 3.6.0. Extended template KeyType to support comparable types in version 3.11.0.
  3. Added in version 3.7.0.
\ No newline at end of file +

See also

  • find find a value in an object
  • count returns the number of occurrences of a key

Version history

  1. Added in version 3.11.0.
  2. Added in version 3.6.0. Extended template KeyType to support comparable types in version 3.11.0.
  3. Added in version 3.7.0.
\ No newline at end of file diff --git a/api/basic_json/contains/index.md b/api/basic_json/contains/index.md new file mode 100644 index 000000000..efef24b69 --- /dev/null +++ b/api/basic_json/contains/index.md @@ -0,0 +1,199 @@ +# nlohmann::basic_json::contains + +``` +// (1) +bool contains(const typename object_t::key_type& key) const; + +// (2) +template +bool contains(KeyType&& key) const; + +// (3) +bool contains(const json_pointer& ptr) const; +``` + +1. Check whether an element exists in a JSON object with a key equivalent to `key`. If the element is not found or the JSON value is not an object, `false` is returned. +1. See 1. This overload is only available if `KeyType` is comparable with `typename object_t::key_type` and `typename object_comparator_t::is_transparent` denotes a type. +1. Check whether the given JSON pointer `ptr` can be resolved in the current JSON value. + +## Template parameters + +`KeyType` : A type for an object key other than [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) that is comparable with [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) using [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). This can also be a string view (C++17). + +## Parameters + +`key` (in) : key value to check its existence. + +`ptr` (in) : JSON pointer to check its existence. + +## Return value + +1. `true` if an element with specified `key` exists. If no such element with such a key is found or the JSON value is not an object, `false` is returned. +1. See 1. +1. `true` if the JSON pointer can be resolved to a stored value, `false` otherwise. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function does not throw exceptions. +1. The function does not throw exceptions. +1. The function does not throw exceptions. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +- This method always returns `false` when executed on a JSON type that is not an object. +- This method can be executed on any JSON value type. + +Postconditions + +If `j.contains(x)` returns `true` for a key or JSON pointer `x`, then it is safe to call `j[x]`. + +## Examples + +Example: (1) check with key + +The example shows how `contains()` is used. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create some JSON values + json j_object = R"( {"key": "value"} )"_json; + json j_array = R"( [1, 2, 3] )"_json; + + // call contains + std::cout << std::boolalpha << + "j_object contains 'key': " << j_object.contains("key") << '\n' << + "j_object contains 'another': " << j_object.contains("another") << '\n' << + "j_array contains 'key': " << j_array.contains("key") << std::endl; +} +``` + +Output: + +``` +j_object contains 'key': true +j_object contains 'another': false +j_array contains 'key': false +``` + +Example: (2) check with key using string_view + +The example shows how `contains()` is used. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create some JSON values + json j_object = R"( {"key": "value"} )"_json; + json j_array = R"( [1, 2, 3] )"_json; + + // call contains + std::cout << std::boolalpha << + "j_object contains 'key': " << j_object.contains("key"sv) << '\n' << + "j_object contains 'another': " << j_object.contains("another"sv) << '\n' << + "j_array contains 'key': " << j_array.contains("key"sv) << std::endl; +} +``` + +Output: + +``` +j_object contains 'key': true +j_object contains 'another': false +j_array contains 'key': false +``` + +Example: (3) check with JSON pointer + +The example shows how `contains()` is used. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + std::cout << std::boolalpha + << j.contains("/number"_json_pointer) << '\n' + << j.contains("/string"_json_pointer) << '\n' + << j.contains("/array"_json_pointer) << '\n' + << j.contains("/array/1"_json_pointer) << '\n' + << j.contains("/array/-"_json_pointer) << '\n' + << j.contains("/array/4"_json_pointer) << '\n' + << j.contains("/baz"_json_pointer) << std::endl; + + try + { + // try to use an array index with leading '0' + j.contains("/array/01"_json_pointer); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + try + { + // try to use an array index that is not a number + j.contains("/array/one"_json_pointer); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +true +true +true +true +false +false +false +``` + +## See also + +- [find](https://json.nlohmann.me/api/basic_json/find/index.md) find a value in an object +- [count](https://json.nlohmann.me/api/basic_json/count/index.md) returns the number of occurrences of a key + +## Version history + +1. Added in version 3.11.0. +1. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0. +1. Added in version 3.7.0. diff --git a/api/basic_json/count.md b/api/basic_json/count.md new file mode 100644 index 000000000..ce51addbd --- /dev/null +++ b/api/basic_json/count.md @@ -0,0 +1,83 @@ +# nlohmann::basic_json::count + +```cpp +// (1) +size_type count(const typename object_t::key_type& key) const; + +// (2) +template +size_type count(KeyType&& key) const; +``` + +1. Returns the number of elements with key `key`. If `ObjectType` is the default `std::map` type, the return value will + always be `0` (`key` was not found) or `1` (`key` was found). +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`key` (in) +: key value of the element to count. + +## Return value + +Number of elements with key `key`. If the JSON value is not an object, the return value will be `0`. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +This method always returns `0` when executed on a JSON type that is not an object. + +## Examples + +??? example "Example: (1) count number of elements" + + The example shows how `count()` is used. + + ```cpp + --8<-- "examples/count__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/count__object_t_key_type.output" + ``` + +??? example "Example: (2) count number of elements using string_view" + + The example shows how `count()` is used. + + ```cpp + --8<-- "examples/count__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/count__keytype.c++17.output" + ``` + +## See also + +- [find](find.md) find a value in an object +- [contains](contains.md) checks whether a key exists + +## Version history + +1. Added in version 3.11.0. +2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0. diff --git a/api/basic_json/count/index.html b/api/basic_json/count/index.html index 4327d2547..7be86cb77 100644 --- a/api/basic_json/count/index.html +++ b/api/basic_json/count/index.html @@ -46,4 +46,4 @@ }

Output:

number of elements with key "two": 1
 number of elements with key "three": 0
-

See also

  • find find a value in an object
  • contains checks whether a key exists

Version history

  1. Added in version 3.11.0.
  2. Added in version 1.0.0. Changed parameter key type to KeyType&& in version 3.11.0.
\ No newline at end of file +

See also

  • find find a value in an object
  • contains checks whether a key exists

Version history

  1. Added in version 3.11.0.
  2. Added in version 1.0.0. Changed parameter key type to KeyType&& in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/count/index.md b/api/basic_json/count/index.md new file mode 100644 index 000000000..da9756c44 --- /dev/null +++ b/api/basic_json/count/index.md @@ -0,0 +1,115 @@ +# nlohmann::basic_json::count + +``` +// (1) +size_type count(const typename object_t::key_type& key) const; + +// (2) +template +size_type count(KeyType&& key) const; +``` + +1. Returns the number of elements with key `key`. If `ObjectType` is the default `std::map` type, the return value will always be `0` (`key` was not found) or `1` (`key` was found). +1. See 1. This overload is only available if `KeyType` is comparable with `typename object_t::key_type` and `typename object_comparator_t::is_transparent` denotes a type. + +## Template parameters + +`KeyType` : A type for an object key other than [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) that is comparable with [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) using [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). This can also be a string view (C++17). + +## Parameters + +`key` (in) : key value of the element to count. + +## Return value + +Number of elements with key `key`. If the JSON value is not an object, the return value will be `0`. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +This method always returns `0` when executed on a JSON type that is not an object. + +## Examples + +Example: (1) count number of elements + +The example shows how `count()` is used. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call count() + auto count_two = j_object.count("two"); + auto count_three = j_object.count("three"); + + // print values + std::cout << "number of elements with key \"two\": " << count_two << '\n'; + std::cout << "number of elements with key \"three\": " << count_three << '\n'; +} +``` + +Output: + +``` +number of elements with key "two": 1 +number of elements with key "three": 0 +``` + +Example: (2) count number of elements using string_view + +The example shows how `count()` is used. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call count() + auto count_two = j_object.count("two"sv); + auto count_three = j_object.count("three"sv); + + // print values + std::cout << "number of elements with key \"two\": " << count_two << '\n'; + std::cout << "number of elements with key \"three\": " << count_three << '\n'; +} +``` + +Output: + +``` +number of elements with key "two": 1 +number of elements with key "three": 0 +``` + +## See also + +- [find](https://json.nlohmann.me/api/basic_json/find/index.md) find a value in an object +- [contains](https://json.nlohmann.me/api/basic_json/contains/index.md) checks whether a key exists + +## Version history + +1. Added in version 3.11.0. +1. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0. diff --git a/api/basic_json/crbegin.md b/api/basic_json/crbegin.md new file mode 100644 index 000000000..95680fb3a --- /dev/null +++ b/api/basic_json/crbegin.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::crbegin + +```cpp +const_reverse_iterator crbegin() const noexcept; +``` + +Returns an iterator to the reverse-beginning; that is, the last element. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `crbegin()`. + + ```cpp + --8<-- "examples/crbegin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/crbegin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/crbegin/index.html b/api/basic_json/crbegin/index.html index 371ae655b..fb4d10394 100644 --- a/api/basic_json/crbegin/index.html +++ b/api/basic_json/crbegin/index.html @@ -16,4 +16,4 @@ std::cout << *it << '\n'; }

Output:

5
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/crbegin/index.md b/api/basic_json/crbegin/index.md new file mode 100644 index 000000000..b33a7b94d --- /dev/null +++ b/api/basic_json/crbegin/index.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::crbegin + +``` +const_reverse_iterator crbegin() const noexcept; +``` + +Returns an iterator to the reverse-beginning; that is, the last element. + +## Return value + +reverse iterator to the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `crbegin()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-beginning + json::const_reverse_iterator it = array.crbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +5 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/crend.md b/api/basic_json/crend.md new file mode 100644 index 000000000..19c581dfe --- /dev/null +++ b/api/basic_json/crend.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::crend + +```cpp +const_reverse_iterator crend() const noexcept; +``` + +Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, +attempting to access it results in undefined behavior. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the element following the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `crend()`. + + ```cpp + --8<-- "examples/crend.cpp" + ``` + + Output: + + ```json + --8<-- "examples/crend.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/crend/index.html b/api/basic_json/crend/index.html index 43906564a..66e3c0aa7 100644 --- a/api/basic_json/crend/index.html +++ b/api/basic_json/crend/index.html @@ -19,4 +19,4 @@ std::cout << *it << '\n'; }

Output:

1
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/crend/index.md b/api/basic_json/crend/index.md new file mode 100644 index 000000000..69fc10cf8 --- /dev/null +++ b/api/basic_json/crend/index.md @@ -0,0 +1,57 @@ +# nlohmann::basic_json::crend + +``` +const_reverse_iterator crend() const noexcept; +``` + +Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior. + +## Return value + +reverse iterator to the element following the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `crend()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-end + json::const_reverse_iterator it = array.crend(); + + // increment the iterator to point to the first element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +1 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/default_object_comparator_t.md b/api/basic_json/default_object_comparator_t.md new file mode 100644 index 000000000..8a237f662 --- /dev/null +++ b/api/basic_json/default_object_comparator_t.md @@ -0,0 +1,35 @@ +# nlohmann::basic_json::default_object_comparator_t + +```cpp +using default_object_comparator_t = std::less; // until C++14 + +using default_object_comparator_t = std::less<>; // since C++14 +``` + +The default comparator used by [`object_t`](object_t.md). + +Since C++14 a transparent comparator is used which prevents unnecessary string construction +when looking up a key in an object. + +The actual comparator used depends on [`object_t`](object_t.md) and can be obtained via +[`object_comparator_t`](object_comparator_t.md). + +## Examples + +??? example + + The example below demonstrates the default comparator. + + ```cpp + --8<-- "examples/default_object_comparator_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/default_object_comparator_t.output" + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/basic_json/default_object_comparator_t/index.html b/api/basic_json/default_object_comparator_t/index.html index 1c89400dd..d9fecf63b 100644 --- a/api/basic_json/default_object_comparator_t/index.html +++ b/api/basic_json/default_object_comparator_t/index.html @@ -14,4 +14,4 @@ }

Output:

one < two : true
 three < four : false
-

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/default_object_comparator_t/index.md b/api/basic_json/default_object_comparator_t/index.md new file mode 100644 index 000000000..324f46656 --- /dev/null +++ b/api/basic_json/default_object_comparator_t/index.md @@ -0,0 +1,44 @@ +# nlohmann::basic_json::default_object_comparator_t + +``` +using default_object_comparator_t = std::less; // until C++14 + +using default_object_comparator_t = std::less<>; // since C++14 +``` + +The default comparator used by [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md). + +Since C++14 a transparent comparator is used which prevents unnecessary string construction when looking up a key in an object. + +The actual comparator used depends on [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md) and can be obtained via [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). + +## Examples + +Example + +The example below demonstrates the default comparator. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha + << "one < two : " << json::default_object_comparator_t{}("one", "two") << "\n" + << "three < four : " << json::default_object_comparator_t{}("three", "four") << std::endl; +} +``` + +Output: + +``` +one < two : true +three < four : false +``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/basic_json/diff.md b/api/basic_json/diff.md new file mode 100644 index 000000000..fb6683ec8 --- /dev/null +++ b/api/basic_json/diff.md @@ -0,0 +1,65 @@ +# nlohmann::basic_json::diff + +```cpp +static basic_json diff(const basic_json& source, + const basic_json& target); +``` + +Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling +[`patch`](patch.md) function. + +For two JSON values `source` and `target`, the following code yields always `#!cpp true`: +```cpp +source.patch(diff(source, target)) == target; +``` + +## Parameters + +`source` (in) +: JSON value to compare from + +`target` (in) +: JSON value to compare against + +## Return value + +a JSON patch to convert the `source` to `target` + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the lengths of `source` and `target`. + +## Notes + +Currently, only `remove`, `add`, and `replace` operations are generated. + +## Examples + +??? example + + The following code shows how a JSON patch is created as a diff for two JSON values. + + ```cpp + --8<-- "examples/diff.cpp" + ``` + + Output: + + ```json + --8<-- "examples/diff.output" + ``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [patch](patch.md) applies a JSON Patch +- [patch_inplace](patch_inplace.md) applies a JSON Patch in place +- [merge_patch](merge_patch.md) applies a JSON Merge Patch + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/diff/index.html b/api/basic_json/diff/index.html index cab179006..afe1ae227 100644 --- a/api/basic_json/diff/index.html +++ b/api/basic_json/diff/index.html @@ -63,4 +63,4 @@ "world" ] } -

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/diff/index.md b/api/basic_json/diff/index.md new file mode 100644 index 000000000..26afd8d22 --- /dev/null +++ b/api/basic_json/diff/index.md @@ -0,0 +1,123 @@ +# nlohmann::basic_json::diff + +``` +static basic_json diff(const basic_json& source, + const basic_json& target); +``` + +Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling [`patch`](https://json.nlohmann.me/api/basic_json/patch/index.md) function. + +For two JSON values `source` and `target`, the following code yields always `true`: + +``` +source.patch(diff(source, target)) == target; +``` + +## Parameters + +`source` (in) : JSON value to compare from + +`target` (in) : JSON value to compare against + +## Return value + +a JSON patch to convert the `source` to `target` + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the lengths of `source` and `target`. + +## Notes + +Currently, only `remove`, `add`, and `replace` operations are generated. + +## Examples + +Example + +The following code shows how a JSON patch is created as a diff for two JSON values. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the source document + json source = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the target document + json target = R"( + { + "baz": "boo", + "hello": [ + "world" + ] + } + )"_json; + + // create the patch + json patch = json::diff(source, target); + + // roundtrip + json patched_source = source.patch(patch); + + // output patch and roundtrip result + std::cout << std::setw(4) << patch << "\n\n" + << std::setw(4) << patched_source << std::endl; +} +``` + +Output: + +``` +[ + { + "op": "replace", + "path": "/baz", + "value": "boo" + }, + { + "op": "remove", + "path": "/foo" + }, + { + "op": "add", + "path": "/hello", + "value": [ + "world" + ] + } +] + +{ + "baz": "boo", + "hello": [ + "world" + ] +} +``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [patch](https://json.nlohmann.me/api/basic_json/patch/index.md) applies a JSON Patch +- [patch_inplace](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md) applies a JSON Patch in place +- [merge_patch](https://json.nlohmann.me/api/basic_json/merge_patch/index.md) applies a JSON Merge Patch + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/dump.md b/api/basic_json/dump.md new file mode 100644 index 000000000..3e50daa1c --- /dev/null +++ b/api/basic_json/dump.md @@ -0,0 +1,85 @@ +# nlohmann::basic_json::dump + +```cpp +string_t dump(const int indent = -1, + const char indent_char = ' ', + const bool ensure_ascii = false, + const error_handler_t error_handler = error_handler_t::strict) const; +``` + +Serialization function for JSON values. The function tries to mimic Python's +[`json.dumps()` function](https://docs.python.org/2/library/json.html#json.dump), and currently supports its `indent` +and `ensure_ascii` parameters. + +## Parameters + +`indent` (in) +: If `indent` is nonnegative, then array elements and object members will be pretty-printed with that indent level. An + indent level of `0` will only insert newlines. `-1` (the default) selects the most compact representation. + +`indent_char` (in) +: The character to use for indentation if `indent` is greater than `0`. The default is ` ` (space). + +`ensure_ascii` (in) +: If `ensure_ascii` is true, all non-ASCII characters in the output are escaped with `\uXXXX` sequences, and the + result consists of ASCII characters only. + +`error_handler` (in) +: how to react on decoding errors; there are three possible values (see [`error_handler_t`](error_handler_t.md): + `strict` (throws an exception in case a decoding error occurs; default), `replace` (replace invalid UTF-8 sequences + with U+FFFD), and `ignore` (ignore invalid UTF-8 sequences during serialization; all valid bytes are copied to the + output unchanged, and invalid bytes are dropped)). + +## Return value + +string containing the serialization of the JSON value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value +is not UTF-8 encoded and `error_handler` is set to `strict` + +## Complexity + +Linear. + +## Notes + +Binary values are serialized as an object containing two keys: + +- "bytes": an array of bytes as integers +- "subtype": the subtype as integer or `#!json null` if the binary has no subtype + +## Examples + +??? example + + The following example shows the effect of different `indent`, `indent_char`, and `ensure_ascii` parameters to the + result of the serialization. + + ```cpp + --8<-- "examples/dump.cpp" + ``` + + Output: + + ```json + --8<-- "examples/dump.output" + ``` + +## See also + +- [to_string](to_string.md) returns a string representation of a JSON value +- [operator<<](../operator_ltlt.md) serialize to stream +- [Serialization](../../features/serialization.md) - the serialization article + +## Version history + +- Added in version 1.0.0. +- Indentation character `indent_char`, option `ensure_ascii` and exceptions added in version 3.0.0. +- Error handlers added in version 3.4.0. +- Serialization of binary values added in version 3.8.0. diff --git a/api/basic_json/dump/index.html b/api/basic_json/dump/index.html index bfd66faa4..68ff3540c 100644 --- a/api/basic_json/dump/index.html +++ b/api/basic_json/dump/index.html @@ -105,4 +105,4 @@ [json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 string with replaced invalid characters: "ä�ü" string with ignored invalid characters: "äü" -

See also

Version history

  • Added in version 1.0.0.
  • Indentation character indent_char, option ensure_ascii and exceptions added in version 3.0.0.
  • Error handlers added in version 3.4.0.
  • Serialization of binary values added in version 3.8.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
  • Indentation character indent_char, option ensure_ascii and exceptions added in version 3.0.0.
  • Error handlers added in version 3.4.0.
  • Serialization of binary values added in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/dump/index.md b/api/basic_json/dump/index.md new file mode 100644 index 000000000..5718c2540 --- /dev/null +++ b/api/basic_json/dump/index.md @@ -0,0 +1,173 @@ +# nlohmann::basic_json::dump + +``` +string_t dump(const int indent = -1, + const char indent_char = ' ', + const bool ensure_ascii = false, + const error_handler_t error_handler = error_handler_t::strict) const; +``` + +Serialization function for JSON values. The function tries to mimic Python's [`json.dumps()` function](https://docs.python.org/2/library/json.html#json.dump), and currently supports its `indent` and `ensure_ascii` parameters. + +## Parameters + +`indent` (in) : If `indent` is nonnegative, then array elements and object members will be pretty-printed with that indent level. An indent level of `0` will only insert newlines. `-1` (the default) selects the most compact representation. + +`indent_char` (in) : The character to use for indentation if `indent` is greater than `0`. The default is (space). + +`ensure_ascii` (in) : If `ensure_ascii` is true, all non-ASCII characters in the output are escaped with `\uXXXX` sequences, and the result consists of ASCII characters only. + +`error_handler` (in) : how to react on decoding errors; there are three possible values (see [`error_handler_t`](https://json.nlohmann.me/api/basic_json/error_handler_t/index.md): `strict` (throws an exception in case a decoding error occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD), and `ignore` (ignore invalid UTF-8 sequences during serialization; all valid bytes are copied to the output unchanged, and invalid bytes are dropped)). + +## Return value + +string containing the serialization of the JSON value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) if a string stored inside the JSON value is not UTF-8 encoded and `error_handler` is set to `strict` + +## Complexity + +Linear. + +## Notes + +Binary values are serialized as an object containing two keys: + +- "bytes": an array of bytes as integers +- "subtype": the subtype as integer or `null` if the binary has no subtype + +## Examples + +Example + +The following example shows the effect of different `indent`, `indent_char`, and `ensure_ascii` parameters to the result of the serialization. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hellö 😀!"; + + // call dump() + std::cout << "objects:" << '\n' + << j_object.dump() << "\n\n" + << j_object.dump(-1) << "\n\n" + << j_object.dump(0) << "\n\n" + << j_object.dump(4) << "\n\n" + << j_object.dump(1, '\t') << "\n\n"; + + std::cout << "arrays:" << '\n' + << j_array.dump() << "\n\n" + << j_array.dump(-1) << "\n\n" + << j_array.dump(0) << "\n\n" + << j_array.dump(4) << "\n\n" + << j_array.dump(1, '\t') << "\n\n"; + + std::cout << "strings:" << '\n' + << j_string.dump() << '\n' + << j_string.dump(-1, ' ', true) << '\n'; + + // create JSON value with invalid UTF-8 byte sequence + json j_invalid = "ä\xA9ü"; + try + { + std::cout << j_invalid.dump() << std::endl; + } + catch (const json::type_error& e) + { + std::cout << e.what() << std::endl; + } + + std::cout << "string with replaced invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace) + << "\nstring with ignored invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore) + << '\n'; +} +``` + +Output: + +``` +objects: +{"one":1,"two":2} + +{"one":1,"two":2} + +{ +"one": 1, +"two": 2 +} + +{ + "one": 1, + "two": 2 +} + +{ + "one": 1, + "two": 2 +} + +arrays: +[1,2,4,8,16] + +[1,2,4,8,16] + +[ +1, +2, +4, +8, +16 +] + +[ + 1, + 2, + 4, + 8, + 16 +] + +[ + 1, + 2, + 4, + 8, + 16 +] + +strings: +"Hellö 😀!" +"Hell\u00f6 \ud83d\ude00!" +[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 +string with replaced invalid characters: "ä�ü" +string with ignored invalid characters: "äü" +``` + +## See also + +- [to_string](https://json.nlohmann.me/api/basic_json/to_string/index.md) returns a string representation of a JSON value +- [operator\<<](https://json.nlohmann.me/api/operator_ltlt/index.md) serialize to stream +- [Serialization](https://json.nlohmann.me/features/serialization/index.md) - the serialization article + +## Version history + +- Added in version 1.0.0. +- Indentation character `indent_char`, option `ensure_ascii` and exceptions added in version 3.0.0. +- Error handlers added in version 3.4.0. +- Serialization of binary values added in version 3.8.0. diff --git a/api/basic_json/emplace.md b/api/basic_json/emplace.md new file mode 100644 index 000000000..18286e83f --- /dev/null +++ b/api/basic_json/emplace.md @@ -0,0 +1,71 @@ +# nlohmann::basic_json::emplace + +```cpp +template +std::pair emplace(Args&& ... args); +``` + +Inserts a new element into a JSON object constructed in-place with the given `args` if there is no element with the key +in the container. If the function is called on a JSON null value, an empty object is created before appending the value +created from `args`. + +## Template parameters + +`Args` +: compatible types to create a `basic_json` object + +## Iterator invalidation + +For [`ordered_json`](../ordered_json.md), adding a value to an object can yield a reallocation, in which case all +iterators (including the `end()` iterator) and all references to the elements are invalidated. + +## Parameters + +`args` (in) +: arguments to forward to a constructor of `basic_json` + +## Return value + +a pair consisting of an iterator to the inserted element, or the already-existing element if no insertion happened, and +a `#!cpp bool` denoting whether the insertion took place. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.311`](../../home/exceptions.md#jsonexceptiontype_error311) when called on a type other than JSON +object or `#!json null`; example: `"cannot use emplace() with number"` + +## Complexity + +Logarithmic in the size of the container, O(log(`size()`)). + +## Examples + +??? example + + The example shows how `emplace()` can be used to add elements to a JSON object. Note how the `#!json null` value was + silently converted to a JSON object. Further note how no value is added if there was already one value stored with + the same key. + + ```cpp + --8<-- "examples/emplace.cpp" + ``` + + Output: + + ```json + --8<-- "examples/emplace.output" + ``` + +## See also + +- [emplace_back](emplace_back.md) add a value to an array +- [insert](insert.md) add values to an array/object +- [Modifying values](../../features/modifying_values.md) - the article on modifying values + +## Version history + +- Since version 2.0.8. diff --git a/api/basic_json/emplace/index.html b/api/basic_json/emplace/index.html index 32f627e8c..ba7d1ecb2 100644 --- a/api/basic_json/emplace/index.html +++ b/api/basic_json/emplace/index.html @@ -37,4 +37,4 @@ 3 true {"A":"a","B":"b"} "b" false -

See also

Version history

  • Since version 2.0.8.
\ No newline at end of file +

See also

Version history

  • Since version 2.0.8.
\ No newline at end of file diff --git a/api/basic_json/emplace/index.md b/api/basic_json/emplace/index.md new file mode 100644 index 000000000..ba4c0f464 --- /dev/null +++ b/api/basic_json/emplace/index.md @@ -0,0 +1,97 @@ +# nlohmann::basic_json::emplace + +``` +template +std::pair emplace(Args&& ... args); +``` + +Inserts a new element into a JSON object constructed in-place with the given `args` if there is no element with the key in the container. If the function is called on a JSON null value, an empty object is created before appending the value created from `args`. + +## Template parameters + +`Args` : compatible types to create a `basic_json` object + +## Iterator invalidation + +For [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), adding a value to an object can yield a reallocation, in which case all iterators (including the `end()` iterator) and all references to the elements are invalidated. + +## Parameters + +`args` (in) : arguments to forward to a constructor of `basic_json` + +## Return value + +a pair consisting of an iterator to the inserted element, or the already-existing element if no insertion happened, and a `bool` denoting whether the insertion took place. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.311`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error311) when called on a type other than JSON object or `null`; example: `"cannot use emplace() with number"` + +## Complexity + +Logarithmic in the size of the container, O(log(`size()`)). + +## Examples + +Example + +The example shows how `emplace()` can be used to add elements to a JSON object. Note how the `null` value was silently converted to a JSON object. Further note how no value is added if there was already one value stored with the same key. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values + auto res1 = object.emplace("three", 3); + null.emplace("A", "a"); + null.emplace("B", "b"); + + // the following call will not add an object, because there is already + // a value stored at key "B" + auto res2 = null.emplace("B", "c"); + + // print values + std::cout << object << '\n'; + std::cout << *res1.first << " " << std::boolalpha << res1.second << '\n'; + + std::cout << null << '\n'; + std::cout << *res2.first << " " << std::boolalpha << res2.second << '\n'; +} +``` + +Output: + +``` +{"one":1,"two":2} +null +{"one":1,"three":3,"two":2} +3 true +{"A":"a","B":"b"} +"b" false +``` + +## See also + +- [emplace_back](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) add a value to an array +- [insert](https://json.nlohmann.me/api/basic_json/insert/index.md) add values to an array/object +- [Modifying values](https://json.nlohmann.me/features/modifying_values/index.md) - the article on modifying values + +## Version history + +- Since version 2.0.8. diff --git a/api/basic_json/emplace_back.md b/api/basic_json/emplace_back.md new file mode 100644 index 000000000..516a66e5d --- /dev/null +++ b/api/basic_json/emplace_back.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::emplace_back + +```cpp +template +reference emplace_back(Args&& ... args); +``` + +Creates a JSON value from the passed parameters `args` to the end of the JSON value. If the function is called on a JSON +`#!json null` value, an empty array is created before appending the value created from `args`. + +## Template parameters + +`Args` +: compatible types to create a `basic_json` object + +## Iterator invalidation + +By adding an element to the end of the array, a reallocation can happen, in which case all iterators (including the +[`end()`](end.md) iterator) and all references to the elements are invalidated. Otherwise, only the [`end()`](end.md) +iterator is invalidated. + +## Parameters + +`args` (in) +: arguments to forward to a constructor of `basic_json` + +## Return value + +reference to the inserted element + +## Exceptions + +Throws [`type_error.311`](../../home/exceptions.md#jsonexceptiontype_error311) when called on a type other than JSON +array or `#!json null`; example: `"cannot use emplace_back() with number"` + +## Complexity + +Amortized constant. + +## Examples + +??? example + + The example shows how `emplace_back()` can be used to add elements to a JSON array. Note how the `null` value was + silently converted to a JSON array. + + ```cpp + --8<-- "examples/emplace_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/emplace_back.output" + ``` + +## See also + +- [operator+=](operator+=.md) add a value to an array/object +- [push_back](push_back.md) add a value to an array/object +- [Modifying values](../../features/modifying_values.md) - the article on modifying values + +## Version history + +- Since version 2.0.8. +- Returns reference since 3.7.0. diff --git a/api/basic_json/emplace_back/index.html b/api/basic_json/emplace_back/index.html index 347bbd3e5..6f55703b1 100644 --- a/api/basic_json/emplace_back/index.html +++ b/api/basic_json/emplace_back/index.html @@ -28,4 +28,4 @@ null [1,2,3,4,5,6] ["first",["second","second","second"]] -

See also

Version history

  • Since version 2.0.8.
  • Returns reference since 3.7.0.
\ No newline at end of file +

See also

Version history

  • Since version 2.0.8.
  • Returns reference since 3.7.0.
\ No newline at end of file diff --git a/api/basic_json/emplace_back/index.md b/api/basic_json/emplace_back/index.md new file mode 100644 index 000000000..d36916261 --- /dev/null +++ b/api/basic_json/emplace_back/index.md @@ -0,0 +1,85 @@ +# nlohmann::basic_json::emplace_back + +``` +template +reference emplace_back(Args&& ... args); +``` + +Creates a JSON value from the passed parameters `args` to the end of the JSON value. If the function is called on a JSON `null` value, an empty array is created before appending the value created from `args`. + +## Template parameters + +`Args` : compatible types to create a `basic_json` object + +## Iterator invalidation + +By adding an element to the end of the array, a reallocation can happen, in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. Otherwise, only the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator is invalidated. + +## Parameters + +`args` (in) : arguments to forward to a constructor of `basic_json` + +## Return value + +reference to the inserted element + +## Exceptions + +Throws [`type_error.311`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error311) when called on a type other than JSON array or `null`; example: `"cannot use emplace_back() with number"` + +## Complexity + +Amortized constant. + +## Examples + +Example + +The example shows how `emplace_back()` can be used to add elements to a JSON array. Note how the `null` value was silently converted to a JSON array. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json array = {1, 2, 3, 4, 5}; + json null; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; + + // add values + array.emplace_back(6); + null.emplace_back("first"); + null.emplace_back(3, "second"); + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; +} +``` + +Output: + +``` +[1,2,3,4,5] +null +[1,2,3,4,5,6] +["first",["second","second","second"]] +``` + +## See also + +- [operator+=](https://json.nlohmann.me/api/basic_json/operator%2B%3D/index.md) add a value to an array/object +- [push_back](https://json.nlohmann.me/api/basic_json/push_back/index.md) add a value to an array/object +- [Modifying values](https://json.nlohmann.me/features/modifying_values/index.md) - the article on modifying values + +## Version history + +- Since version 2.0.8. +- Returns reference since 3.7.0. diff --git a/api/basic_json/empty.md b/api/basic_json/empty.md new file mode 100644 index 000000000..8d566738d --- /dev/null +++ b/api/basic_json/empty.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::empty + +```cpp +bool empty() const noexcept; +``` + +Checks if a JSON value has no elements (i.e., whether its [`size()`](size.md) is `0`). + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +|------------|----------------------------------------| +| null | `#!cpp true` | +| boolean | `#!cpp false` | +| string | `#!cpp false` | +| number | `#!cpp false` | +| binary | `#!cpp false` | +| object | result of function `object_t::empty()` | +| array | result of function `array_t::empty()` | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the +[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `empty()` functions have +constant complexity. + +## Possible implementation + +```cpp +bool empty() const noexcept +{ + return size() == 0; +} +``` + +## Notes + +This function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container +itself is empty which is `#!cpp false` in the case of a string. + +## Examples + +??? example + + The following code uses `empty()` to check if a JSON object contains any elements. + + ```cpp + --8<-- "examples/empty.cpp" + ``` + + Output: + + ```json + --8<-- "examples/empty.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Extended to return `#!cpp false` for binary types in version 3.8.0. diff --git a/api/basic_json/empty/index.html b/api/basic_json/empty/index.html index 7fa92d096..c98725bb6 100644 --- a/api/basic_json/empty/index.html +++ b/api/basic_json/empty/index.html @@ -42,4 +42,4 @@ false true false -

Version history

  • Added in version 1.0.0.
  • Extended to return false for binary types in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
  • Extended to return false for binary types in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/empty/index.md b/api/basic_json/empty/index.md new file mode 100644 index 000000000..50ff8a9c0 --- /dev/null +++ b/api/basic_json/empty/index.md @@ -0,0 +1,100 @@ +# nlohmann::basic_json::empty + +``` +bool empty() const noexcept; +``` + +Checks if a JSON value has no elements (i.e., whether its [`size()`](https://json.nlohmann.me/api/basic_json/size/index.md) is `0`). + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +| ---------- | -------------------------------------- | +| null | `true` | +| boolean | `false` | +| string | `false` | +| number | `false` | +| binary | `false` | +| object | result of function `object_t::empty()` | +| array | result of function `array_t::empty()` | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md) and [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md) satisfy the [Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `empty()` functions have constant complexity. + +## Possible implementation + +``` +bool empty() const noexcept +{ + return size() == 0; +} +``` + +## Notes + +This function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container itself is empty which is `false` in the case of a string. + +## Examples + +Example + +The following code uses `empty()` to check if a JSON object contains any elements. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call empty() + std::cout << std::boolalpha; + std::cout << j_null.empty() << '\n'; + std::cout << j_boolean.empty() << '\n'; + std::cout << j_number_integer.empty() << '\n'; + std::cout << j_number_float.empty() << '\n'; + std::cout << j_object.empty() << '\n'; + std::cout << j_object_empty.empty() << '\n'; + std::cout << j_array.empty() << '\n'; + std::cout << j_array_empty.empty() << '\n'; + std::cout << j_string.empty() << '\n'; +} +``` + +Output: + +``` +true +false +false +false +false +true +false +true +false +``` + +## Version history + +- Added in version 1.0.0. +- Extended to return `false` for binary types in version 3.8.0. diff --git a/api/basic_json/end.md b/api/basic_json/end.md new file mode 100644 index 000000000..179ce9e67 --- /dev/null +++ b/api/basic_json/end.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::end + +```cpp +iterator end() noexcept; +const_iterator end() const noexcept; +``` + +Returns an iterator to one past the last element. + +![Illustration from cppreference.com](../../images/range-begin-end.svg) + +## Return value + +iterator one past the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `end()`. + + ```cpp + --8<-- "examples/end.cpp" + ``` + + Output: + + ```json + --8<-- "examples/end.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/end/index.html b/api/basic_json/end/index.html index 36f2ae66f..30541334e 100644 --- a/api/basic_json/end/index.html +++ b/api/basic_json/end/index.html @@ -20,4 +20,4 @@ std::cout << *it << '\n'; }

Output:

5
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/end/index.md b/api/basic_json/end/index.md new file mode 100644 index 000000000..597960bfc --- /dev/null +++ b/api/basic_json/end/index.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json::end + +``` +iterator end() noexcept; +const_iterator end() const noexcept; +``` + +Returns an iterator to one past the last element. + +## Return value + +iterator one past the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `end()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to one past the last element + json::iterator it = array.end(); + + // decrement the iterator to point to the last element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +5 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/end_pos.md b/api/basic_json/end_pos.md new file mode 100644 index 000000000..95b07297f --- /dev/null +++ b/api/basic_json/end_pos.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::end_pos + +```cpp +#if JSON_DIAGNOSTIC_POSITIONS +constexpr std::size_t end_pos() const noexcept; +#endif +``` + +Returns the position immediately following the last character of the JSON string from which the value was parsed from. + +| JSON type | return value | +|-----------|-----------------------------------| +| object | position after the closing `}` | +| array | position after the closing `]` | +| string | position after the closing `"` | +| number | position after the last character | +| boolean | position after `e` | +| null | position after `l` | + +## Return value + +the position of the character _following_ the last character of the given value in the parsed JSON string, if the +value was created by the [`parse`](parse.md) function, or `std::string::npos` if the value was constructed otherwise + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +!!! note "Note" + + The function is only available if macro [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) has + been defined to `#!cpp 1` before including the library header. + +!!! warning "Invalidation" + + The returned positions are only valid as long as the JSON value is not changed. The positions are *not* updated + when the JSON value is changed. + +## Examples + +??? example "Example" + + ```cpp + --8<-- "examples/diagnostic_positions.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostic_positions.output" + ``` + + The output shows the start/end positions of all the objects and fields in the JSON string. + +## See also + +- [start_pos](start_pos.md) to access the start position +- [JSON_DIAGNOSTIC_POSITIONS](../macros/json_diagnostic_positions.md) for an overview of the diagnostic positions + +## Version history + +- Added in version 3.12.0. diff --git a/api/basic_json/end_pos/index.html b/api/basic_json/end_pos/index.html index f1f62c6d9..bd3f8197a 100644 --- a/api/basic_json/end_pos/index.html +++ b/api/basic_json/end_pos/index.html @@ -101,4 +101,4 @@ Original string: 1 Parsed string: 1 -

The output shows the start/end positions of all the objects and fields in the JSON string.

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file +

The output shows the start/end positions of all the objects and fields in the JSON string.

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file diff --git a/api/basic_json/end_pos/index.md b/api/basic_json/end_pos/index.md new file mode 100644 index 000000000..87a4e9422 --- /dev/null +++ b/api/basic_json/end_pos/index.md @@ -0,0 +1,163 @@ +# nlohmann::basic_json::end_pos + +``` +#if JSON_DIAGNOSTIC_POSITIONS +constexpr std::size_t end_pos() const noexcept; +#endif +``` + +Returns the position immediately following the last character of the JSON string from which the value was parsed from. + +| JSON type | return value | +| --------- | --------------------------------- | +| object | position after the closing `}` | +| array | position after the closing `]` | +| string | position after the closing `"` | +| number | position after the last character | +| boolean | position after `e` | +| null | position after `l` | + +## Return value + +the position of the character *following* the last character of the given value in the parsed JSON string, if the value was created by the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function, or `std::string::npos` if the value was constructed otherwise + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +Note + +The function is only available if macro [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) has been defined to `1` before including the library header. + +Invalidation + +The returned positions are only valid as long as the JSON value is not changed. The positions are *not* updated when the JSON value is changed. + +## Examples + +Example + +``` +#include + +#define JSON_DIAGNOSTIC_POSITIONS 1 +#include + +using json = nlohmann::json; + +int main() +{ + std::string json_string = R"( + { + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } + )"; + json j = json::parse(json_string); + + std::cout << "Root diagnostic positions: \n"; + std::cout << "\tstart_pos: " << j.start_pos() << '\n'; + std::cout << "\tend_pos:" << j.end_pos() << "\n"; + std::cout << "Original string: \n"; + std::cout << "{\n \"address\": {\n \"street\": \"Fake Street\",\n \"housenumber\": 1\n }\n }" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << "\n\n"; + + std::cout << "address diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "{ \"street\": \"Fake Street\",\n \"housenumber\": 1\n }" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"].start_pos(), j["address"].end_pos() - j["address"].start_pos()) << "\n\n"; + + std::cout << "street diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"]["street"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"]["street"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "\"Fake Street\"" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"]["street"].start_pos(), j["address"]["street"].end_pos() - j["address"]["street"].start_pos()) << "\n\n"; + + std::cout << "housenumber diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"]["housenumber"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"]["housenumber"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "1" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"]["housenumber"].start_pos(), j["address"]["housenumber"].end_pos() - j["address"]["housenumber"].start_pos()) << "\n\n"; +} +``` + +Output: + +``` +Root diagnostic positions: + start_pos: 5 + end_pos:109 +Original string: +{ + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } +Parsed string: +{ + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } + +address diagnostic positions: + start_pos:26 + end_pos:103 + +Original string: +{ "street": "Fake Street", + "housenumber": 1 + } +Parsed string: +{ + "street": "Fake Street", + "housenumber": 1 + } + +street diagnostic positions: + start_pos:50 + end_pos:63 + +Original string: +"Fake Street" +Parsed string: +"Fake Street" + +housenumber diagnostic positions: + start_pos:92 + end_pos:93 + +Original string: +1 +Parsed string: +1 +``` + +The output shows the start/end positions of all the objects and fields in the JSON string. + +## See also + +- [start_pos](https://json.nlohmann.me/api/basic_json/start_pos/index.md) to access the start position +- [JSON_DIAGNOSTIC_POSITIONS](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) for an overview of the diagnostic positions + +## Version history + +- Added in version 3.12.0. diff --git a/api/basic_json/erase.md b/api/basic_json/erase.md new file mode 100644 index 000000000..d1e6d6d22 --- /dev/null +++ b/api/basic_json/erase.md @@ -0,0 +1,217 @@ +# nlohmann::basic_json::erase + +```cpp +// (1) +iterator erase(iterator pos); +const_iterator erase(const_iterator pos); + +// (2) +iterator erase(iterator first, iterator last); +const_iterator erase(const_iterator first, const_iterator last); + +// (3) +size_type erase(const typename object_t::key_type& key); + +// (4) +template +size_type erase(KeyType&& key); + +// (5) +void erase(const size_type idx); +``` + +1. Removes an element from a JSON value specified by iterator `pos`. The iterator `pos` must be valid and + dereferenceable. Thus, the `end()` iterator (which is valid, but is not dereferenceable) cannot be used as a value for + `pos`. + + If called on a primitive type other than `#!json null`, the resulting JSON value will be `#!json null`. + +2. Remove an element range specified by `[first; last)` from a JSON value. The iterator `first` does not need to be + dereferenceable if `first == last`: erasing an empty range is a no-op. + + If called on a primitive type other than `#!json null`, the resulting JSON value will be `#!json null`. + +3. Removes an element from a JSON object by key. + +4. See 3. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +5. Removes an element from a JSON array by index. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`pos` (in) +: iterator to the element to remove + +`first` (in) +: iterator to the beginning of the range to remove + +`last` (in) +: iterator past the end of the range to remove + +`key` (in) +: object key of the elements to remove + +`idx` (in) +: array index of the element to remove + +## Return value + +1. Iterator following the last removed element. If the iterator `pos` refers to the last element, the `end()` iterator + is returned. +2. Iterator following the last removed element. If the iterator `last` refers to the last element, the `end()` iterator + is returned. +3. Number of elements removed. If `ObjectType` is the default `std::map` type, the return value will always be `0` + (`key` was not found) or `1` (`key` was found). +4. See 3. +5. (none) + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if called on a `null` value; + example: `"cannot use erase() with null"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.205`](../../home/exceptions.md#jsonexceptioninvalid_iterator205) if called on a + primitive type with invalid iterator (i.e., any iterator which is not `begin()`); example: `"iterator out of + range"` +2. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) if called on a `null` value; + example: `"cannot use erase() with null"` + - Throws [`invalid_iterator.203`](../../home/exceptions.md#jsonexceptioninvalid_iterator203) if called on iterators + which does not belong to the current JSON value; example: `"iterators do not fit current value"` + - Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if called on a + primitive type with invalid iterators (i.e., if `first != begin()` and `last != end()`); example: `"iterators out + of range"` +3. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) when called on a type other than + JSON object; example: `"cannot use erase() with null"` +4. See 3. +5. The function can throw the following exceptions: + - Throws [`type_error.307`](../../home/exceptions.md#jsonexceptiontype_error307) when called on a type other than + JSON array; example: `"cannot use erase() with null"` + - Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) when `idx >= size()`; example: + `"array index 17 is out of range"` + +## Complexity + +1. The complexity depends on the type: + - objects: amortized constant + - arrays: linear in distance between `pos` and the end of the container + - strings and binary: linear in the length of the member + - other types: constant +2. The complexity depends on the type: + - objects: `log(size()) + std::distance(first, last)` + - arrays: linear in the distance between `first` and `last`, plus linear + in the distance between `last` and end of the container + - strings and binary: linear in the length of the member + - other types: constant +3. `log(size()) + count(key)` +4. `log(size()) + count(key)` +5. Linear in distance between `idx` and the end of the container. + +## Notes + +1. Invalidates iterators and references at or after the point of the `erase`, including the `end()` iterator. +2. (none) +3. References and iterators to the erased elements are invalidated. Other references and iterators are not affected. +4. See 3. +5. (none) + +## Examples + +??? example "Example: (1) remove element given an iterator" + + The example shows the effect of `erase()` for different JSON types using an iterator. + + ```cpp + --8<-- "examples/erase__IteratorType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__IteratorType.output" + ``` + +??? example "Example: (2) remove elements given an iterator range" + + The example shows the effect of `erase()` for different JSON types using an iterator range. + + ```cpp + --8<-- "examples/erase__IteratorType_IteratorType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__IteratorType_IteratorType.output" + ``` + +??? example "Example: (3) remove element from a JSON object given a key" + + The example shows the effect of `erase()` for different JSON types using an object key. + + ```cpp + --8<-- "examples/erase__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__object_t_key_type.output" + ``` + +??? example "Example: (4) remove element from a JSON object given a key using string_view" + + The example shows the effect of `erase()` for different JSON types using an object key. + + ```cpp + --8<-- "examples/erase__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__keytype.c++17.output" + ``` + +??? example "Example: (5) remove element from a JSON array given an index" + + The example shows the effect of `erase()` using an array index. + + ```cpp + --8<-- "examples/erase__size_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/erase__size_type.output" + ``` + +## See also + +- [clear](clear.md) clears the contents +- [insert](insert.md) add values to an array/object +- [Modifying values](../../features/modifying_values.md) - the article on modifying values + +## Version history + +1. Added in version 1.0.0. Added support for binary types in version 3.8.0. +2. Added in version 1.0.0. Added support for binary types in version 3.8.0. +3. Added in version 1.0.0. +4. Added in version 3.11.0. +5. Added in version 1.0.0. diff --git a/api/basic_json/erase/index.html b/api/basic_json/erase/index.html index e3983e283..02221b7d5 100644 --- a/api/basic_json/erase/index.html +++ b/api/basic_json/erase/index.html @@ -148,4 +148,4 @@ std::cout << j_array << '\n'; }

Output:

[0,1,3,4,5]
-

See also

Version history

  1. Added in version 1.0.0. Added support for binary types in version 3.8.0.
  2. Added in version 1.0.0. Added support for binary types in version 3.8.0.
  3. Added in version 1.0.0.
  4. Added in version 3.11.0.
  5. Added in version 1.0.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0. Added support for binary types in version 3.8.0.
  2. Added in version 1.0.0. Added support for binary types in version 3.8.0.
  3. Added in version 1.0.0.
  4. Added in version 3.11.0.
  5. Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/erase/index.md b/api/basic_json/erase/index.md new file mode 100644 index 000000000..bb08b6b04 --- /dev/null +++ b/api/basic_json/erase/index.md @@ -0,0 +1,313 @@ +# nlohmann::basic_json::erase + +``` +// (1) +iterator erase(iterator pos); +const_iterator erase(const_iterator pos); + +// (2) +iterator erase(iterator first, iterator last); +const_iterator erase(const_iterator first, const_iterator last); + +// (3) +size_type erase(const typename object_t::key_type& key); + +// (4) +template +size_type erase(KeyType&& key); + +// (5) +void erase(const size_type idx); +``` + +1. Removes an element from a JSON value specified by iterator `pos`. The iterator `pos` must be valid and dereferenceable. Thus, the `end()` iterator (which is valid, but is not dereferenceable) cannot be used as a value for `pos`. + + If called on a primitive type other than `null`, the resulting JSON value will be `null`. + +1. Remove an element range specified by `[first; last)` from a JSON value. The iterator `first` does not need to be dereferenceable if `first == last`: erasing an empty range is a no-op. + + If called on a primitive type other than `null`, the resulting JSON value will be `null`. + +1. Removes an element from a JSON object by key. + +1. See 3. This overload is only available if `KeyType` is comparable with `typename object_t::key_type` and `typename object_comparator_t::is_transparent` denotes a type. + +1. Removes an element from a JSON array by index. + +## Template parameters + +`KeyType` : A type for an object key other than [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) that is comparable with [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) using [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). This can also be a string view (C++17). + +## Parameters + +`pos` (in) : iterator to the element to remove + +`first` (in) : iterator to the beginning of the range to remove + +`last` (in) : iterator past the end of the range to remove + +`key` (in) : object key of the elements to remove + +`idx` (in) : array index of the element to remove + +## Return value + +1. Iterator following the last removed element. If the iterator `pos` refers to the last element, the `end()` iterator is returned. +1. Iterator following the last removed element. If the iterator `last` refers to the last element, the `end()` iterator is returned. +1. Number of elements removed. If `ObjectType` is the default `std::map` type, the return value will always be `0` (`key` was not found) or `1` (`key` was found). +1. See 3. +1. (none) + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.307`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error307) if called on a `null` value; example: `"cannot use erase() with null"` + - Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) if called on an iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.205`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator205) if called on a primitive type with invalid iterator (i.e., any iterator which is not `begin()`); example: `"iterator out of range"` +1. The function can throw the following exceptions: + - Throws [`type_error.307`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error307) if called on a `null` value; example: `"cannot use erase() with null"` + - Throws [`invalid_iterator.203`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator203) if called on iterators which does not belong to the current JSON value; example: `"iterators do not fit current value"` + - Throws [`invalid_iterator.204`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator204) if called on a primitive type with invalid iterators (i.e., if `first != begin()` and `last != end()`); example: `"iterators out of range"` +1. The function can throw the following exceptions: + - Throws [`type_error.307`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error307) when called on a type other than JSON object; example: `"cannot use erase() with null"` +1. See 3. +1. The function can throw the following exceptions: + - Throws [`type_error.307`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error307) when called on a type other than JSON array; example: `"cannot use erase() with null"` + - Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) when `idx >= size()`; example: `"array index 17 is out of range"` + +## Complexity + +1. The complexity depends on the type: + - objects: amortized constant + - arrays: linear in distance between `pos` and the end of the container + - strings and binary: linear in the length of the member + - other types: constant +1. The complexity depends on the type: + - objects: `log(size()) + std::distance(first, last)` + - arrays: linear in the distance between `first` and `last`, plus linear in the distance between `last` and end of the container + - strings and binary: linear in the length of the member + - other types: constant +1. `log(size()) + count(key)` +1. `log(size()) + count(key)` +1. Linear in distance between `idx` and the end of the container. + +## Notes + +1. Invalidates iterators and references at or after the point of the `erase`, including the `end()` iterator. +1. (none) +1. References and iterators to the erased elements are invalidated. Other references and iterators are not affected. +1. See 3. +1. (none) + +## Examples + +Example: (1) remove element given an iterator + +The example shows the effect of `erase()` for different JSON types using an iterator. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call erase() + j_boolean.erase(j_boolean.begin()); + j_number_integer.erase(j_number_integer.begin()); + j_number_float.erase(j_number_float.begin()); + j_object.erase(j_object.find("two")); + j_array.erase(j_array.begin() + 2); + j_string.erase(j_string.begin()); + + // print values + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} +``` + +Output: + +``` +null +null +null +{"one":1} +[1,2,8,16] +null +``` + +Example: (2) remove elements given an iterator range + +The example shows the effect of `erase()` for different JSON types using an iterator range. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call erase() + j_boolean.erase(j_boolean.begin(), j_boolean.end()); + j_number_integer.erase(j_number_integer.begin(), j_number_integer.end()); + j_number_float.erase(j_number_float.begin(), j_number_float.end()); + j_object.erase(j_object.find("two"), j_object.end()); + j_array.erase(j_array.begin() + 1, j_array.begin() + 3); + j_string.erase(j_string.begin(), j_string.end()); + + // print values + std::cout << j_boolean << '\n'; + std::cout << j_number_integer << '\n'; + std::cout << j_number_float << '\n'; + std::cout << j_object << '\n'; + std::cout << j_array << '\n'; + std::cout << j_string << '\n'; +} +``` + +Output: + +``` +null +null +null +{"one":1} +[1,8,16] +null +``` + +Example: (3) remove element from a JSON object given a key + +The example shows the effect of `erase()` for different JSON types using an object key. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call erase() + auto count_one = j_object.erase("one"); + auto count_three = j_object.erase("three"); + + // print values + std::cout << j_object << '\n'; + std::cout << count_one << " " << count_three << '\n'; +} +``` + +Output: + +``` +{"two":2} +1 0 +``` + +Example: (4) remove element from a JSON object given a key using string_view + +The example shows the effect of `erase()` for different JSON types using an object key. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call erase() + auto count_one = j_object.erase("one"sv); + auto count_three = j_object.erase("three"sv); + + // print values + std::cout << j_object << '\n'; + std::cout << count_one << " " << count_three << '\n'; +} +``` + +Output: + +``` +{"two":2} +1 0 +``` + +Example: (5) remove element from a JSON array given an index + +The example shows the effect of `erase()` using an array index. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json j_array = {0, 1, 2, 3, 4, 5}; + + // call erase() + j_array.erase(2); + + // print values + std::cout << j_array << '\n'; +} +``` + +Output: + +``` +[0,1,3,4,5] +``` + +## See also + +- [clear](https://json.nlohmann.me/api/basic_json/clear/index.md) clears the contents +- [insert](https://json.nlohmann.me/api/basic_json/insert/index.md) add values to an array/object +- [Modifying values](https://json.nlohmann.me/features/modifying_values/index.md) - the article on modifying values + +## Version history + +1. Added in version 1.0.0. Added support for binary types in version 3.8.0. +1. Added in version 1.0.0. Added support for binary types in version 3.8.0. +1. Added in version 1.0.0. +1. Added in version 3.11.0. +1. Added in version 1.0.0. diff --git a/api/basic_json/error_handler_t.md b/api/basic_json/error_handler_t.md new file mode 100644 index 000000000..f20c33c03 --- /dev/null +++ b/api/basic_json/error_handler_t.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::error_handler_t + +```cpp +enum class error_handler_t { + strict, + replace, + ignore +}; +``` + +This enumeration is used in the [`dump`](dump.md) function to choose how to treat decoding errors while serializing a +`basic_json` value. Three values are differentiated: + +strict +: throw a `type_error` exception in case of invalid UTF-8 + +replace +: replace invalid UTF-8 sequences with U+FFFD (� REPLACEMENT CHARACTER) + +ignore +: ignore invalid UTF-8 sequences; all valid bytes are copied to the output unchanged, and invalid bytes are dropped + +## Examples + +??? example + + The example below shows how the different values of the `error_handler_t` influence the behavior of + [`dump`](dump.md) when reading serializing an invalid UTF-8 sequence. + + ```cpp + --8<-- "examples/error_handler_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/error_handler_t.output" + ``` + +## Version history + +- Added in version 3.4.0. diff --git a/api/basic_json/error_handler_t/index.html b/api/basic_json/error_handler_t/index.html index 25b84779a..d444e8ff1 100644 --- a/api/basic_json/error_handler_t/index.html +++ b/api/basic_json/error_handler_t/index.html @@ -30,4 +30,4 @@

Output:

[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9
 string with replaced invalid characters: "ä�ü"
 string with ignored invalid characters: "äü"
-

Version history

  • Added in version 3.4.0.
\ No newline at end of file +

Version history

  • Added in version 3.4.0.
\ No newline at end of file diff --git a/api/basic_json/error_handler_t/index.md b/api/basic_json/error_handler_t/index.md new file mode 100644 index 000000000..0270de4cb --- /dev/null +++ b/api/basic_json/error_handler_t/index.md @@ -0,0 +1,62 @@ +# nlohmann::basic_json::error_handler_t + +``` +enum class error_handler_t { + strict, + replace, + ignore +}; +``` + +This enumeration is used in the [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) function to choose how to treat decoding errors while serializing a `basic_json` value. Three values are differentiated: + +strict : throw a `type_error` exception in case of invalid UTF-8 + +replace : replace invalid UTF-8 sequences with U+FFFD (� REPLACEMENT CHARACTER) + +ignore : ignore invalid UTF-8 sequences; all valid bytes are copied to the output unchanged, and invalid bytes are dropped + +## Examples + +Example + +The example below shows how the different values of the `error_handler_t` influence the behavior of [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) when reading serializing an invalid UTF-8 sequence. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON value with invalid UTF-8 byte sequence + json j_invalid = "ä\xA9ü"; + try + { + std::cout << j_invalid.dump() << std::endl; + } + catch (const json::type_error& e) + { + std::cout << e.what() << std::endl; + } + + std::cout << "string with replaced invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace) + << "\nstring with ignored invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore) + << '\n'; +} +``` + +Output: + +``` +[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 +string with replaced invalid characters: "ä�ü" +string with ignored invalid characters: "äü" +``` + +## Version history + +- Added in version 3.4.0. diff --git a/api/basic_json/exception.md b/api/basic_json/exception.md new file mode 100644 index 000000000..b592d62ee --- /dev/null +++ b/api/basic_json/exception.md @@ -0,0 +1,87 @@ +# nlohmann::basic_json::exception + +```cpp +class exception : public std::exception; +``` + +This class is an extension of [`std::exception`](https://en.cppreference.com/w/cpp/error/exception) objects with a +member `id` for exception ids. It is used as the base class for all exceptions thrown by the `basic_json` class. This +class can hence be used as "wildcard" to catch exceptions, see example below. + +```mermaid +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_exception fill:#CCCCFF +``` + +Subclasses: + +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Notes + +To have nothrow-copy-constructible exceptions, we internally use `std::runtime_error` which can cope with +arbitrary-length error messages. Intermediate strings are built with static functions and then passed to the actual +constructor. + +## Examples + +??? example + + The following code shows how arbitrary library exceptions can be caught. + + ```cpp + --8<-- "examples/exception.cpp" + ``` + + Output: + + ```json + --8<-- "examples/exception.output" + ``` + +## See also + +[List of exceptions](../../home/exceptions.md) + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/exception/index.html b/api/basic_json/exception/index.html index 6d770529d..3e287170c 100644 --- a/api/basic_json/exception/index.html +++ b/api/basic_json/exception/index.html @@ -49,4 +49,4 @@ }

Output:

message: [json.exception.out_of_range.403] key 'non-existing' not found
 exception id: 403
-

See also

List of exceptions

Version history

  • Since version 3.0.0.
\ No newline at end of file +

See also

List of exceptions

Version history

  • Since version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/exception/index.md b/api/basic_json/exception/index.md new file mode 100644 index 000000000..1608726e6 --- /dev/null +++ b/api/basic_json/exception/index.md @@ -0,0 +1,103 @@ +# nlohmann::basic_json::exception + +``` +class exception : public std::exception; +``` + +This class is an extension of [`std::exception`](https://en.cppreference.com/w/cpp/error/exception) objects with a member `id` for exception ids. It is used as the base class for all exceptions thrown by the `basic_json` class. This class can hence be used as "wildcard" to catch exceptions, see example below. + +``` +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_exception fill:#CCCCFF +``` + +Subclasses: + +- [`parse_error`](https://json.nlohmann.me/api/basic_json/parse_error/index.md) for exceptions indicating a parse error +- [`invalid_iterator`](https://json.nlohmann.me/api/basic_json/invalid_iterator/index.md) for exceptions indicating errors with iterators +- [`type_error`](https://json.nlohmann.me/api/basic_json/type_error/index.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](https://json.nlohmann.me/api/basic_json/out_of_range/index.md) for exceptions indicating access out of the defined range +- [`other_error`](https://json.nlohmann.me/api/basic_json/other_error/index.md) for exceptions indicating other library errors + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Notes + +To have nothrow-copy-constructible exceptions, we internally use `std::runtime_error` which can cope with arbitrary-length error messages. Intermediate strings are built with static functions and then passed to the actual constructor. + +## Examples + +Example + +The following code shows how arbitrary library exceptions can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling at() for a non-existing key + json j = {{"foo", "bar"}}; + json k = j.at("non-existing"); + } + catch (const json::exception& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.out_of_range.403] key 'non-existing' not found +exception id: 403 +``` + +## See also + +[List of exceptions](https://json.nlohmann.me/home/exceptions/index.md) + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/find.md b/api/basic_json/find.md new file mode 100644 index 000000000..35ff9dcb2 --- /dev/null +++ b/api/basic_json/find.md @@ -0,0 +1,87 @@ +# nlohmann::basic_json::find + +```cpp +// (1) +iterator find(const typename object_t::key_type& key); +const_iterator find(const typename object_t::key_type& key) const; + +// (2) +template +iterator find(KeyType&& key); +template +const_iterator find(KeyType&& key) const; +``` + +1. Finds an element in a JSON object with a key equivalent to `key`. If the element is not found or the + JSON value is not an object, `end()` is returned. +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Parameters + +`key` (in) +: key value of the element to search for. + +## Return value + +Iterator to an element with a key equivalent to `key`. If no such element is found or the JSON value is not an object, +a past-the-end iterator (see `end()`) is returned. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +This method always returns `end()` when executed on a JSON type that is not an object. + +## Examples + +??? example "Example: (1) find object element by key" + + The example shows how `find()` is used. + + ```cpp + --8<-- "examples/find__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/find__object_t_key_type.output" + ``` + +??? example "Example: (2) find object element by key using string_view" + + The example shows how `find()` is used. + + ```cpp + --8<-- "examples/find__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/find__keytype.c++17.output" + ``` + +## See also + +- [count](count.md) returns the number of occurrences of a key +- [contains](contains.md) checks whether a key exists + +## Version history + +1. Added in version 3.11.0. +2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0. diff --git a/api/basic_json/find/index.html b/api/basic_json/find/index.html index 72124f4d0..02f9740f5 100644 --- a/api/basic_json/find/index.html +++ b/api/basic_json/find/index.html @@ -55,4 +55,4 @@

Output:

"two" was found: true
 value at key "two": 2
 "three" was found: false
-

See also

  • count returns the number of occurrences of a key
  • contains checks whether a key exists

Version history

  1. Added in version 3.11.0.
  2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.
\ No newline at end of file +

See also

  • count returns the number of occurrences of a key
  • contains checks whether a key exists

Version history

  1. Added in version 3.11.0.
  2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/find/index.md b/api/basic_json/find/index.md new file mode 100644 index 000000000..ded810600 --- /dev/null +++ b/api/basic_json/find/index.md @@ -0,0 +1,124 @@ +# nlohmann::basic_json::find + +``` +// (1) +iterator find(const typename object_t::key_type& key); +const_iterator find(const typename object_t::key_type& key) const; + +// (2) +template +iterator find(KeyType&& key); +template +const_iterator find(KeyType&& key) const; +``` + +1. Finds an element in a JSON object with a key equivalent to `key`. If the element is not found or the JSON value is not an object, `end()` is returned. +1. See 1. This overload is only available if `KeyType` is comparable with `typename object_t::key_type` and `typename object_comparator_t::is_transparent` denotes a type. + +## Template parameters + +`KeyType` : A type for an object key other than [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) that is comparable with [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) using [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). This can also be a string view (C++17). + +## Parameters + +`key` (in) : key value of the element to search for. + +## Return value + +Iterator to an element with a key equivalent to `key`. If no such element is found or the JSON value is not an object, a past-the-end iterator (see `end()`) is returned. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Logarithmic in the size of the JSON object. + +## Notes + +This method always returns `end()` when executed on a JSON type that is not an object. + +## Examples + +Example: (1) find object element by key + +The example shows how `find()` is used. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call find + auto it_two = j_object.find("two"); + auto it_three = j_object.find("three"); + + // print values + std::cout << std::boolalpha; + std::cout << "\"two\" was found: " << (it_two != j_object.end()) << '\n'; + std::cout << "value at key \"two\": " << *it_two << '\n'; + std::cout << "\"three\" was found: " << (it_three != j_object.end()) << '\n'; +} +``` + +Output: + +``` +"two" was found: true +value at key "two": 2 +"three" was found: false +``` + +Example: (2) find object element by key using string_view + +The example shows how `find()` is used. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j_object = {{"one", 1}, {"two", 2}}; + + // call find + auto it_two = j_object.find("two"sv); + auto it_three = j_object.find("three"sv); + + // print values + std::cout << std::boolalpha; + std::cout << "\"two\" was found: " << (it_two != j_object.end()) << '\n'; + std::cout << "value at key \"two\": " << *it_two << '\n'; + std::cout << "\"three\" was found: " << (it_three != j_object.end()) << '\n'; +} +``` + +Output: + +``` +"two" was found: true +value at key "two": 2 +"three" was found: false +``` + +## See also + +- [count](https://json.nlohmann.me/api/basic_json/count/index.md) returns the number of occurrences of a key +- [contains](https://json.nlohmann.me/api/basic_json/contains/index.md) checks whether a key exists + +## Version history + +1. Added in version 3.11.0. +1. Added in version 1.0.0. Changed to support comparable types in version 3.11.0. diff --git a/api/basic_json/flatten.md b/api/basic_json/flatten.md new file mode 100644 index 000000000..7b26a8900 --- /dev/null +++ b/api/basic_json/flatten.md @@ -0,0 +1,50 @@ +# nlohmann::basic_json::flatten + +```cpp +basic_json flatten() const; +``` + +The function creates a JSON object whose keys are JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901)) +and whose values are all primitive (see [`is_primitive()`](is_primitive.md) for more information). The original JSON +value can be restored using the [`unflatten()`](unflatten.md) function. + +## Return value + +an object that maps JSON pointers to primitive values + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +Empty objects and arrays are flattened to `#!json null` and will not be reconstructed correctly by the +[`unflatten()`](unflatten.md) function. + +## Examples + +??? example + + The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers. + + ```cpp + --8<-- "examples/flatten.cpp" + ``` + + Output: + + ```json + --8<-- "examples/flatten.output" + ``` + +## See also + +- [unflatten](unflatten.md) the reverse function + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/flatten/index.html b/api/basic_json/flatten/index.html index ea72f1fe1..ef392975c 100644 --- a/api/basic_json/flatten/index.html +++ b/api/basic_json/flatten/index.html @@ -43,4 +43,4 @@ "/object/value": 42.99, "/pi": 3.141 } -

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/flatten/index.md b/api/basic_json/flatten/index.md new file mode 100644 index 000000000..9bdfa8a07 --- /dev/null +++ b/api/basic_json/flatten/index.md @@ -0,0 +1,89 @@ +# nlohmann::basic_json::flatten + +``` +basic_json flatten() const; +``` + +The function creates a JSON object whose keys are JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all primitive (see [`is_primitive()`](https://json.nlohmann.me/api/basic_json/is_primitive/index.md) for more information). The original JSON value can be restored using the [`unflatten()`](https://json.nlohmann.me/api/basic_json/unflatten/index.md) function. + +## Return value + +an object that maps JSON pointers to primitive values + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +Empty objects and arrays are flattened to `null` and will not be reconstructed correctly by the [`unflatten()`](https://json.nlohmann.me/api/basic_json/unflatten/index.md) function. + +## Examples + +Example + +The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON value + json j = + { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + { + "answer", { + {"everything", 42} + } + }, + {"list", {1, 0, 2}}, + { + "object", { + {"currency", "USD"}, + {"value", 42.99} + } + } + }; + + // call flatten() + std::cout << std::setw(4) << j.flatten() << '\n'; +} +``` + +Output: + +``` +{ + "/answer/everything": 42, + "/happy": true, + "/list/0": 1, + "/list/1": 0, + "/list/2": 2, + "/name": "Niels", + "/nothing": null, + "/object/currency": "USD", + "/object/value": 42.99, + "/pi": 3.141 +} +``` + +## See also + +- [unflatten](https://json.nlohmann.me/api/basic_json/unflatten/index.md) the reverse function + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/format_as.md b/api/basic_json/format_as.md new file mode 100644 index 000000000..b35d0ddcd --- /dev/null +++ b/api/basic_json/format_as.md @@ -0,0 +1,95 @@ +# format_as(basic_json) + +```cpp +template +std::string format_as(const BasicJsonType& j); +``` + +This function implements the [`format_as`](https://fmt.dev/latest/api/#formatting-user-defined-types) +customization point used by the [{fmt}](https://github.com/fmtlib/fmt) library (fmtlib). It has no +dependency on any `fmt` header and no effect at all unless a caller's translation unit also includes +`fmt` and calls `fmt::format`/`fmt::print` on a JSON value. + +## Template parameters + +`BasicJsonType` +: a specialization of [`basic_json`](index.md) + +## Return value + +string containing the serialization of the JSON value (same as [`dump()`](dump.md)) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value +is not UTF-8 encoded + +## Complexity + +Linear. + +## Possible implementation + +```cpp +template +std::string format_as(const BasicJsonType& j) +{ + return j.dump(); +} +``` + +## Notes + +!!! warning "Version-dependent effect on fmt" + + `fmt` only picks up a `format_as` overload that returns a `std::string` in fmt **10.0.0 through + 11.0.2**. Starting with fmt **11.1.0**, `fmt` restricts automatic `format_as` pickup to overloads that + return an arithmetic type, so this function has no effect there (it is simply unused, not a compile + error). + + If you use fmt \>= 11.1.0, or want the same pretty-print spec support that + [`std::formatter`](std_formatter.md) has (`#!cpp "{:#}"`, a width to set the indent such + as `#!cpp "{:2}"`/`#!cpp "{:#2}"`, and fill-and-align to pick the indent character such as + `#!cpp "{:.>#}"`), define your own `fmt::formatter` specialization mirroring the same logic: + + ```cpp + --8<-- "../../../tests/fmt_formatter/project/main.cpp:formatter_recipe" + ``` + + This recipe isn't shipped by the library itself, since doing so would make `fmt` a build dependency + (see the FAQ entry on + [using JSON values with `std::format` or `fmt`](../../home/faq.md#using-json-values-with-stdformat-or-fmt) + for more background) — but it *is* compiled and exercised against a real, current `fmt` release as + part of the library's own test suite (`tests/fmt_formatter`, via CMake `FetchContent`), so it's kept in + sync with `std::formatter` and verified to actually work, not just illustrative. + +## Examples + +??? example + + The following code shows how the library's `format_as()` function integrates with `fmt::format`, + allowing argument-dependent lookup. + + ```cpp + --8<-- "examples/format_as.cpp" + ``` + + Output: + + ```json + --8<-- "examples/format_as.output" + ``` + +## See also + +- [dump](dump.md) +- [std::formatter](std_formatter.md) - the `std::format` (C++20) equivalent +- [Serialization](../../features/serialization.md) - the serialization article + +## Version history + +- Added in version 3.12.x. diff --git a/api/basic_json/format_as/index.html b/api/basic_json/format_as/index.html index bc2e2ebdb..8578dac1e 100644 --- a/api/basic_json/format_as/index.html +++ b/api/basic_json/format_as/index.html @@ -84,4 +84,4 @@ std::cout << j_str << std::endl; }

Output:

{"one":1,"two":2}
-

See also

Version history

  • Added in version 3.12.x.
\ No newline at end of file +

See also

Version history

  • Added in version 3.12.x.
\ No newline at end of file diff --git a/api/basic_json/format_as/index.md b/api/basic_json/format_as/index.md new file mode 100644 index 000000000..e0b59ded6 --- /dev/null +++ b/api/basic_json/format_as/index.md @@ -0,0 +1,154 @@ +# format_as(basic_json) + +``` +template +std::string format_as(const BasicJsonType& j); +``` + +This function implements the [`format_as`](https://fmt.dev/latest/api/#formatting-user-defined-types) customization point used by the [{fmt}](https://github.com/fmtlib/fmt) library (fmtlib). It has no dependency on any `fmt` header and no effect at all unless a caller's translation unit also includes `fmt` and calls `fmt::format`/`fmt::print` on a JSON value. + +## Template parameters + +`BasicJsonType` : a specialization of [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) + +## Return value + +string containing the serialization of the JSON value (same as [`dump()`](https://json.nlohmann.me/api/basic_json/dump/index.md)) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) if a string stored inside the JSON value is not UTF-8 encoded + +## Complexity + +Linear. + +## Possible implementation + +``` +template +std::string format_as(const BasicJsonType& j) +{ + return j.dump(); +} +``` + +## Notes + +Version-dependent effect on fmt + +`fmt` only picks up a `format_as` overload that returns a `std::string` in fmt **10.0.0 through 11.0.2**. Starting with fmt **11.1.0**, `fmt` restricts automatic `format_as` pickup to overloads that return an arithmetic type, so this function has no effect there (it is simply unused, not a compile error). + +If you use fmt >= 11.1.0, or want the same pretty-print spec support that [`std::formatter`](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) has (`"{:#}"`, a width to set the indent such as `"{:2}"`/`"{:#2}"`, and fill-and-align to pick the indent character such as `"{:.>#}"`), define your own `fmt::formatter` specialization mirroring the same logic: + +``` +template <> +struct fmt::formatter +{ + // -1 means compact output (dump()); any value >= 0 means pretty-printed + // output with that many spaces (or indent_char) per level. + int indent = -1; + char indent_char = ' '; + + constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator + { + auto it = ctx.begin(); + const auto end = ctx.end(); + constexpr auto is_align = [](char c) + { + return c == '<' || c == '>' || c == '^'; + }; + + // [[fill] align] - repurposed here to pick a custom indent character + if (it != end && it + 1 != end && is_align(it[1])) + { + indent_char = *it; + it += 2; + } + else if (it != end && is_align(*it)) + { + ++it; + } + + // ['#'] - "alternate form", used here to request pretty-printing with a + // default indent of 4 (overridden by an explicit width below, if given) + if (it != end && *it == '#') + { + indent = 4; + ++it; + } + + // [width] - repurposed here to pick the indent size; a width without '#' + // implies pretty-printing since an indent otherwise has no meaning + if (it != end && *it >= '1' && *it <= '9') + { + indent = 0; + while (it != end && *it >= '0' && *it <= '9') + { + indent = (indent * 10) + (*it - '0'); + ++it; + } + } + + if (it != end && *it != '}') + { + throw fmt::format_error("invalid format args for nlohmann::json"); + } + + return it; + } + + auto format(const nlohmann::json& j, format_context& ctx) const + { + const auto dumped = j.dump(indent, indent_char); + return fmt::format_to(ctx.out(), "{}", dumped); + } +}; +``` + +This recipe isn't shipped by the library itself, since doing so would make `fmt` a build dependency (see the FAQ entry on [using JSON values with `std::format` or `fmt`](https://json.nlohmann.me/home/faq/#using-json-values-with-stdformat-or-fmt) for more background) — but it *is* compiled and exercised against a real, current `fmt` release as part of the library's own test suite (`tests/fmt_formatter`, via CMake `FetchContent`), so it's kept in sync with `std::formatter` and verified to actually work, not just illustrative. + +## Examples + +Example + +The following code shows how the library's `format_as()` function integrates with `fmt::format`, allowing argument-dependent lookup. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json j = {{"one", 1}, {"two", 2}}; + + // format_as() is found via argument-dependent lookup, the same way + // fmt::format/fmt::print would find it + auto j_str = format_as(j); + + std::cout << j_str << std::endl; +} +``` + +Output: + +``` +{"one":1,"two":2} +``` + +## See also + +- [dump](https://json.nlohmann.me/api/basic_json/dump/index.md) +- [std::formatter](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) - the `std::format` (C++20) equivalent +- [Serialization](https://json.nlohmann.me/features/serialization/index.md) - the serialization article + +## Version history + +- Added in version 3.12.x. diff --git a/api/basic_json/from_bjdata.md b/api/basic_json/from_bjdata.md new file mode 100644 index 000000000..274444aab --- /dev/null +++ b/api/basic_json/from_bjdata.md @@ -0,0 +1,103 @@ +# nlohmann::basic_json::from_bjdata + +```cpp +// (1) +template +static basic_json from_bjdata(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_bjdata(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the BJData (Binary JData) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/bjdata.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in BJData format convertible to an input adapter + +`first` (in) +: iterator to the start of the input + +`last` (in) +: iterator to the end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string could not be parsed + successfully +- Throws [out_of_range.408](../../home/exceptions.md#jsonexceptionout_of_range408) if the size of an optimized container + or n-dimensional array cannot be represented by `std::size_t` + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in BJData format to a JSON value. + + ```cpp + --8<-- "examples/from_bjdata.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bjdata.output" + ``` + +## See also + +- [to_bjdata](to_bjdata.md) create a BJData serialization of a JSON value +- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format +- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format +- [from_bson](from_bson.md) create a JSON value from an input in BSON format +- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format + +## Version history + +- Added in version 3.11.0. diff --git a/api/basic_json/from_bjdata/index.html b/api/basic_json/from_bjdata/index.html index 3d8578ed4..2a7bcdf7d 100644 --- a/api/basic_json/from_bjdata/index.html +++ b/api/basic_json/from_bjdata/index.html @@ -32,4 +32,4 @@ "compact": true, "schema": 0 } -

See also

  • to_bjdata create a BJData serialization of a JSON value
  • from_cbor create a JSON value from an input in CBOR format
  • from_msgpack create a JSON value from an input in MessagePack format
  • from_bson create a JSON value from an input in BSON format
  • from_ubjson create a JSON value from an input in UBJSON format

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

See also

  • to_bjdata create a BJData serialization of a JSON value
  • from_cbor create a JSON value from an input in CBOR format
  • from_msgpack create a JSON value from an input in MessagePack format
  • from_bson create a JSON value from an input in BSON format
  • from_ubjson create a JSON value from an input in UBJSON format

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/from_bjdata/index.md b/api/basic_json/from_bjdata/index.md new file mode 100644 index 000000000..06fbfeb1b --- /dev/null +++ b/api/basic_json/from_bjdata/index.md @@ -0,0 +1,116 @@ +# nlohmann::basic_json::from_bjdata + +``` +// (1) +template +static basic_json from_bjdata(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_bjdata(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the BJData (Binary JData) serialization format. + +1. Reads from a compatible input. +1. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/bjdata/index.md). + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. +``` + +`IteratorType` : a compatible iterator type + +## Parameters + +`i` (in) : an input in BJData format convertible to an input adapter + +`first` (in) : iterator to the start of the input + +`last` (in) : iterator to the end of the input + +`strict` (in) : whether to expect the input to be consumed until EOF (`true` by default) + +`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `false`, the return value will be `value_t::discarded`. The latter can be checked with [`is_discarded`](https://json.nlohmann.me/api/basic_json/is_discarded/index.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error110) if the given input ends prematurely or the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error112) if a parse error occurs +- Throws [parse_error.113](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error113) if a string could not be parsed successfully +- Throws [out_of_range.408](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range408) if the size of an optimized container or n-dimensional array cannot be represented by `std::size_t` + +## Complexity + +Linear in the size of the input. + +## Examples + +Example + +The example shows the deserialization of a byte vector in BJData format to a JSON value. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, + 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D + }; + + // deserialize it with BJData + json j = json::from_bjdata(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` + +## See also + +- [to_bjdata](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) create a BJData serialization of a JSON value +- [from_cbor](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) create a JSON value from an input in CBOR format +- [from_msgpack](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md) create a JSON value from an input in MessagePack format +- [from_bson](https://json.nlohmann.me/api/basic_json/from_bson/index.md) create a JSON value from an input in BSON format +- [from_ubjson](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md) create a JSON value from an input in UBJSON format + +## Version history + +- Added in version 3.11.0. diff --git a/api/basic_json/from_bson.md b/api/basic_json/from_bson.md new file mode 100644 index 000000000..41389c151 --- /dev/null +++ b/api/basic_json/from_bson.md @@ -0,0 +1,115 @@ +# nlohmann::basic_json::from_bson + +```cpp +// (1) +template +static basic_json from_bson(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_bson(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the BSON (Binary JSON) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/bson.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in BSON format convertible to an input adapter + +`first` (in) +: iterator to the start of the input + +`last` (in) +: iterator to the end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.110`](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of the input was not reached when `strict` was set to true +- Throws [`parse_error.112`](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs (e.g., an + invalid string or byte array length) +- Throws [`parse_error.114`](../../home/exceptions.md#jsonexceptionparse_error114) if an unsupported BSON record type is + encountered + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in BSON format to a JSON value. + + ```cpp + --8<-- "examples/from_bson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bson.output" + ``` + +## See also + +- [BSON specification](http://bsonspec.org/spec.html) +- [to_bson](to_bson.md) for the analogous serialization +- [from_cbor](from_cbor.md) for the related CBOR format +- [from_msgpack](from_msgpack.md) for the related MessagePack format +- [from_ubjson](from_ubjson.md) for the related UBJSON format +- [from_bjdata](from_bjdata.md) for the related BJData format + +## Version history + +- Added in version 3.4.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_bson` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_bson(ptr, len, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_bson` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_bson({ptr, ptr+len}, ...);` with `#!cpp from_bson(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/api/basic_json/from_bson/index.html b/api/basic_json/from_bson/index.html index de1663bc5..e60907ae2 100644 --- a/api/basic_json/from_bson/index.html +++ b/api/basic_json/from_bson/index.html @@ -33,4 +33,4 @@ "compact": true, "schema": 0 } -

See also

Version history

  • Added in version 3.4.0.

Deprecation

  • Overload (2) replaces calls to from_bson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_bson(ptr, len, ...); with from_bson(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_bson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_bson({ptr, ptr+len}, ...); with from_bson(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file +

See also

Version history

  • Added in version 3.4.0.

Deprecation

  • Overload (2) replaces calls to from_bson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_bson(ptr, len, ...); with from_bson(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_bson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_bson({ptr, ptr+len}, ...); with from_bson(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file diff --git a/api/basic_json/from_bson/index.md b/api/basic_json/from_bson/index.md new file mode 100644 index 000000000..a0592fdba --- /dev/null +++ b/api/basic_json/from_bson/index.md @@ -0,0 +1,124 @@ +# nlohmann::basic_json::from_bson + +``` +// (1) +template +static basic_json from_bson(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_bson(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the BSON (Binary JSON) serialization format. + +1. Reads from a compatible input. +1. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/bson/index.md). + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. +``` + +`IteratorType` : a compatible iterator type + +## Parameters + +`i` (in) : an input in BSON format convertible to an input adapter + +`first` (in) : iterator to the start of the input + +`last` (in) : iterator to the end of the input + +`strict` (in) : whether to expect the input to be consumed until EOF (`true` by default) + +`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `false`, the return value will be `value_t::discarded`. The latter can be checked with [`is_discarded`](https://json.nlohmann.me/api/basic_json/is_discarded/index.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.110`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error110) if the given input ends prematurely or the end of the input was not reached when `strict` was set to true +- Throws [`parse_error.112`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error112) if a parse error occurs (e.g., an invalid string or byte array length) +- Throws [`parse_error.114`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error114) if an unsupported BSON record type is encountered + +## Complexity + +Linear in the size of the input. + +## Examples + +Example + +The example shows the deserialization of a byte vector in BSON format to a JSON value. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 + }; + + // deserialize it with BSON + json j = json::from_bson(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` + +## See also + +- [BSON specification](http://bsonspec.org/spec.html) +- [to_bson](https://json.nlohmann.me/api/basic_json/to_bson/index.md) for the analogous serialization +- [from_cbor](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) for the related CBOR format +- [from_msgpack](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md) for the related MessagePack format +- [from_ubjson](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md) for the related UBJSON format +- [from_bjdata](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md) for the related BJData format + +## Version history + +- Added in version 3.4.0. + +Deprecation + +- Overload (2) replaces calls to `from_bson` with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_bson(ptr, len, ...);` with `from_bson(ptr, ptr+len, ...);`. +- Overload (2) replaces calls to `from_bson` with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_bson({ptr, ptr+len}, ...);` with `from_bson(ptr, ptr+len, ...);`. + +You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated function. diff --git a/api/basic_json/from_cbor.md b/api/basic_json/from_cbor.md new file mode 100644 index 000000000..d29c7bf7b --- /dev/null +++ b/api/basic_json/from_cbor.md @@ -0,0 +1,125 @@ +# nlohmann::basic_json::from_cbor + +```cpp +// (1) +template +static basic_json from_cbor(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); + +// (2) +template +static basic_json from_cbor(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); +``` + +Deserializes a given input to a JSON value using the CBOR (Concise Binary Object Representation) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/cbor.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in CBOR format convertible to an input adapter + +`first` (in) +: iterator to the start of the input + +`last` (in) +: iterator to the end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +`tag_handler` (in) +: how to treat CBOR tags (optional, `error` by default); see [`cbor_tag_handler_t`](cbor_tag_handler_t.md) for more + information + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from CBOR were + used in the given input or if the input is not valid CBOR +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as a map key, + but not found + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in CBOR format to a JSON value. + + ```cpp + --8<-- "examples/from_cbor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_cbor.output" + ``` + +## See also + +- [to_cbor](to_cbor.md) create a CBOR serialization of a JSON value +- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format +- [from_bson](from_bson.md) create a JSON value from an input in BSON format +- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format +- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format + +## Version history + +- Added in version 2.0.9. +- Parameter `start_index` since version 2.1.1. +- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0. +- Added `allow_exceptions` parameter in version 3.2.0. +- Added `tag_handler` parameter in version 3.9.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_cbor` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_cbor(ptr, len, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_cbor({ptr, ptr+len}, ...);` with `#!cpp from_cbor(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/api/basic_json/from_cbor/index.html b/api/basic_json/from_cbor/index.html index efdc219f6..e835469ab 100644 --- a/api/basic_json/from_cbor/index.html +++ b/api/basic_json/from_cbor/index.html @@ -35,4 +35,4 @@ "compact": true, "schema": 0 } -

See also

  • to_cbor create a CBOR serialization of a JSON value
  • from_msgpack create a JSON value from an input in MessagePack format
  • from_bson create a JSON value from an input in BSON format
  • from_ubjson create a JSON value from an input in UBJSON format
  • from_bjdata create a JSON value from an input in BJData format

Version history

  • Added in version 2.0.9.
  • Parameter start_index since version 2.1.1.
  • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • Added allow_exceptions parameter in version 3.2.0.
  • Added tag_handler parameter in version 3.9.0.

Deprecation

  • Overload (2) replaces calls to from_cbor with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_cbor(ptr, len, ...); with from_cbor(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_cbor with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_cbor({ptr, ptr+len}, ...); with from_cbor(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file +

See also

  • to_cbor create a CBOR serialization of a JSON value
  • from_msgpack create a JSON value from an input in MessagePack format
  • from_bson create a JSON value from an input in BSON format
  • from_ubjson create a JSON value from an input in UBJSON format
  • from_bjdata create a JSON value from an input in BJData format

Version history

  • Added in version 2.0.9.
  • Parameter start_index since version 2.1.1.
  • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • Added allow_exceptions parameter in version 3.2.0.
  • Added tag_handler parameter in version 3.9.0.

Deprecation

  • Overload (2) replaces calls to from_cbor with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_cbor(ptr, len, ...); with from_cbor(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_cbor with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_cbor({ptr, ptr+len}, ...); with from_cbor(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file diff --git a/api/basic_json/from_cbor/index.md b/api/basic_json/from_cbor/index.md new file mode 100644 index 000000000..217f61127 --- /dev/null +++ b/api/basic_json/from_cbor/index.md @@ -0,0 +1,131 @@ +# nlohmann::basic_json::from_cbor + +``` +// (1) +template +static basic_json from_cbor(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); + +// (2) +template +static basic_json from_cbor(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error); +``` + +Deserializes a given input to a JSON value using the CBOR (Concise Binary Object Representation) serialization format. + +1. Reads from a compatible input. +1. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/cbor/index.md). + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. +``` + +`IteratorType` : a compatible iterator type + +## Parameters + +`i` (in) : an input in CBOR format convertible to an input adapter + +`first` (in) : iterator to the start of the input + +`last` (in) : iterator to the end of the input + +`strict` (in) : whether to expect the input to be consumed until EOF (`true` by default) + +`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default) + +`tag_handler` (in) : how to treat CBOR tags (optional, `error` by default); see [`cbor_tag_handler_t`](https://json.nlohmann.me/api/basic_json/cbor_tag_handler_t/index.md) for more information + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `false`, the return value will be `value_t::discarded`. The latter can be checked with [`is_discarded`](https://json.nlohmann.me/api/basic_json/is_discarded/index.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error110) if the given input ends prematurely or the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error112) if unsupported features from CBOR were used in the given input or if the input is not valid CBOR +- Throws [parse_error.113](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error113) if a string was expected as a map key, but not found + +## Complexity + +Linear in the size of the input. + +## Examples + +Example + +The example shows the deserialization of a byte vector in CBOR format to a JSON value. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, + 0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x00 + }; + + // deserialize it with CBOR + json j = json::from_cbor(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` + +## See also + +- [to_cbor](https://json.nlohmann.me/api/basic_json/to_cbor/index.md) create a CBOR serialization of a JSON value +- [from_msgpack](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md) create a JSON value from an input in MessagePack format +- [from_bson](https://json.nlohmann.me/api/basic_json/from_bson/index.md) create a JSON value from an input in BSON format +- [from_ubjson](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md) create a JSON value from an input in UBJSON format +- [from_bjdata](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md) create a JSON value from an input in BJData format + +## Version history + +- Added in version 2.0.9. +- Parameter `start_index` since version 2.1.1. +- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0. +- Added `allow_exceptions` parameter in version 3.2.0. +- Added `tag_handler` parameter in version 3.9.0. + +Deprecation + +- Overload (2) replaces calls to `from_cbor` with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_cbor(ptr, len, ...);` with `from_cbor(ptr, ptr+len, ...);`. +- Overload (2) replaces calls to `from_cbor` with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_cbor({ptr, ptr+len}, ...);` with `from_cbor(ptr, ptr+len, ...);`. + +You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated function. diff --git a/api/basic_json/from_msgpack.md b/api/basic_json/from_msgpack.md new file mode 100644 index 000000000..12469bca0 --- /dev/null +++ b/api/basic_json/from_msgpack.md @@ -0,0 +1,117 @@ +# nlohmann::basic_json::from_msgpack + +```cpp +// (1) +template +static basic_json from_msgpack(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_msgpack(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the MessagePack serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/messagepack.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in MessagePack format convertible to an input adapter + +`first` (in) +: iterator to the start of the input + +`last` (in) +: iterator to the end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if unsupported features from + MessagePack were used in the given input or if the input is not valid MessagePack +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string was expected as a map key, + but not found + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in MessagePack format to a JSON value. + + ```cpp + --8<-- "examples/from_msgpack.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_msgpack.output" + ``` + +## See also + +- [to_msgpack](to_msgpack.md) create a MessagePack serialization of a JSON value +- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format +- [from_bson](from_bson.md) create a JSON value from an input in BSON format +- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format +- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format + +## Version history + +- Added in version 2.0.9. +- Parameter `start_index` since version 2.1.1. +- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0. +- Added `allow_exceptions` parameter in version 3.2.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_msgpack` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_msgpack(ptr, len, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_msgpack` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_msgpack({ptr, ptr+len}, ...);` with `#!cpp from_msgpack(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/api/basic_json/from_msgpack/index.html b/api/basic_json/from_msgpack/index.html index 55458a694..07d6e2604 100644 --- a/api/basic_json/from_msgpack/index.html +++ b/api/basic_json/from_msgpack/index.html @@ -32,4 +32,4 @@ "compact": true, "schema": 0 } -

See also

  • to_msgpack create a MessagePack serialization of a JSON value
  • from_cbor create a JSON value from an input in CBOR format
  • from_bson create a JSON value from an input in BSON format
  • from_ubjson create a JSON value from an input in UBJSON format
  • from_bjdata create a JSON value from an input in BJData format

Version history

  • Added in version 2.0.9.
  • Parameter start_index since version 2.1.1.
  • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • Added allow_exceptions parameter in version 3.2.0.

Deprecation

  • Overload (2) replaces calls to from_msgpack with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_msgpack(ptr, len, ...); with from_msgpack(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_msgpack with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_msgpack({ptr, ptr+len}, ...); with from_msgpack(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file +

See also

  • to_msgpack create a MessagePack serialization of a JSON value
  • from_cbor create a JSON value from an input in CBOR format
  • from_bson create a JSON value from an input in BSON format
  • from_ubjson create a JSON value from an input in UBJSON format
  • from_bjdata create a JSON value from an input in BJData format

Version history

  • Added in version 2.0.9.
  • Parameter start_index since version 2.1.1.
  • Changed to consume input adapters, removed start_index parameter, and added strict parameter in version 3.0.0.
  • Added allow_exceptions parameter in version 3.2.0.

Deprecation

  • Overload (2) replaces calls to from_msgpack with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_msgpack(ptr, len, ...); with from_msgpack(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_msgpack with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_msgpack({ptr, ptr+len}, ...); with from_msgpack(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file diff --git a/api/basic_json/from_msgpack/index.md b/api/basic_json/from_msgpack/index.md new file mode 100644 index 000000000..9e443d88b --- /dev/null +++ b/api/basic_json/from_msgpack/index.md @@ -0,0 +1,125 @@ +# nlohmann::basic_json::from_msgpack + +``` +// (1) +template +static basic_json from_msgpack(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_msgpack(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the MessagePack serialization format. + +1. Reads from a compatible input. +1. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/messagepack/index.md). + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. +``` + +`IteratorType` : a compatible iterator type + +## Parameters + +`i` (in) : an input in MessagePack format convertible to an input adapter + +`first` (in) : iterator to the start of the input + +`last` (in) : iterator to the end of the input + +`strict` (in) : whether to expect the input to be consumed until EOF (`true` by default) + +`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `false`, the return value will be `value_t::discarded`. The latter can be checked with [`is_discarded`](https://json.nlohmann.me/api/basic_json/is_discarded/index.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error110) if the given input ends prematurely or the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error112) if unsupported features from MessagePack were used in the given input or if the input is not valid MessagePack +- Throws [parse_error.113](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error113) if a string was expected as a map key, but not found + +## Complexity + +Linear in the size of the input. + +## Examples + +Example + +The example shows the deserialization of a byte vector in MessagePack format to a JSON value. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, + 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x00 + }; + + // deserialize it with MessagePack + json j = json::from_msgpack(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` + +## See also + +- [to_msgpack](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) create a MessagePack serialization of a JSON value +- [from_cbor](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) create a JSON value from an input in CBOR format +- [from_bson](https://json.nlohmann.me/api/basic_json/from_bson/index.md) create a JSON value from an input in BSON format +- [from_ubjson](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md) create a JSON value from an input in UBJSON format +- [from_bjdata](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md) create a JSON value from an input in BJData format + +## Version history + +- Added in version 2.0.9. +- Parameter `start_index` since version 2.1.1. +- Changed to consume input adapters, removed `start_index` parameter, and added `strict` parameter in version 3.0.0. +- Added `allow_exceptions` parameter in version 3.2.0. + +Deprecation + +- Overload (2) replaces calls to `from_msgpack` with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_msgpack(ptr, len, ...);` with `from_msgpack(ptr, ptr+len, ...);`. +- Overload (2) replaces calls to `from_msgpack` with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_msgpack({ptr, ptr+len}, ...);` with `from_msgpack(ptr, ptr+len, ...);`. + +You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated function. diff --git a/api/basic_json/from_ubjson.md b/api/basic_json/from_ubjson.md new file mode 100644 index 000000000..a6621473d --- /dev/null +++ b/api/basic_json/from_ubjson.md @@ -0,0 +1,116 @@ +# nlohmann::basic_json::from_ubjson + +```cpp +// (1) +template +static basic_json from_ubjson(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_ubjson(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the UBJSON (Universal Binary JSON) serialization format. + +1. Reads from a compatible input. +2. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/ubjson.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type + +## Parameters + +`i` (in) +: an input in UBJSON format convertible to an input adapter + +`first` (in) +: iterator to the start of the input + +`last` (in) +: iterator to the end of the input + +`strict` (in) +: whether to expect the input to be consumed until EOF (`#!cpp true` by default) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](../../home/exceptions.md#jsonexceptionparse_error110) if the given input ends prematurely or + the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](../../home/exceptions.md#jsonexceptionparse_error112) if a parse error occurs +- Throws [parse_error.113](../../home/exceptions.md#jsonexceptionparse_error113) if a string could not be parsed + successfully +- Throws [out_of_range.408](../../home/exceptions.md#jsonexceptionout_of_range408) if the size of an optimized container + or n-dimensional array cannot be represented by `std::size_t` + +## Complexity + +Linear in the size of the input. + +## Examples + +??? example + + The example shows the deserialization of a byte vector in UBJSON format to a JSON value. + + ```cpp + --8<-- "examples/from_ubjson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_ubjson.output" + ``` + +## See also + +- [to_ubjson](to_ubjson.md) create a UBJSON serialization of a JSON value +- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format +- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format +- [from_bson](from_bson.md) create a JSON value from an input in BSON format +- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format + +## Version history + +- Added in version 3.1.0. +- Added `allow_exceptions` parameter in version 3.2.0. + +!!! warning "Deprecation" + + - Overload (2) replaces calls to `from_ubjson` with a pointer and a length as first two parameters, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_ubjson(ptr, len, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`. + - Overload (2) replaces calls to `from_ubjson` with a pair of iterators as their first parameter, which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp from_ubjson({ptr, ptr+len}, ...);` with `#!cpp from_ubjson(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/api/basic_json/from_ubjson/index.html b/api/basic_json/from_ubjson/index.html index 408186926..454536431 100644 --- a/api/basic_json/from_ubjson/index.html +++ b/api/basic_json/from_ubjson/index.html @@ -32,4 +32,4 @@ "compact": true, "schema": 0 } -

See also

  • to_ubjson create a UBJSON serialization of a JSON value
  • from_cbor create a JSON value from an input in CBOR format
  • from_msgpack create a JSON value from an input in MessagePack format
  • from_bson create a JSON value from an input in BSON format
  • from_bjdata create a JSON value from an input in BJData format

Version history

  • Added in version 3.1.0.
  • Added allow_exceptions parameter in version 3.2.0.

Deprecation

  • Overload (2) replaces calls to from_ubjson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_ubjson(ptr, len, ...); with from_ubjson(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_ubjson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_ubjson({ptr, ptr+len}, ...); with from_ubjson(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file +

See also

  • to_ubjson create a UBJSON serialization of a JSON value
  • from_cbor create a JSON value from an input in CBOR format
  • from_msgpack create a JSON value from an input in MessagePack format
  • from_bson create a JSON value from an input in BSON format
  • from_bjdata create a JSON value from an input in BJData format

Version history

  • Added in version 3.1.0.
  • Added allow_exceptions parameter in version 3.2.0.

Deprecation

  • Overload (2) replaces calls to from_ubjson with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_ubjson(ptr, len, ...); with from_ubjson(ptr, ptr+len, ...);.
  • Overload (2) replaces calls to from_ubjson with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like from_ubjson({ptr, ptr+len}, ...); with from_ubjson(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file diff --git a/api/basic_json/from_ubjson/index.md b/api/basic_json/from_ubjson/index.md new file mode 100644 index 000000000..f164d6345 --- /dev/null +++ b/api/basic_json/from_ubjson/index.md @@ -0,0 +1,124 @@ +# nlohmann::basic_json::from_ubjson + +``` +// (1) +template +static basic_json from_ubjson(InputType&& i, + const bool strict = true, + const bool allow_exceptions = true); +// (2) +template +static basic_json from_ubjson(IteratorType first, IteratorType last, + const bool strict = true, + const bool allow_exceptions = true); +``` + +Deserializes a given input to a JSON value using the UBJSON (Universal Binary JSON) serialization format. + +1. Reads from a compatible input. +1. Reads from an iterator range. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/ubjson/index.md). + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. +``` + +`IteratorType` : a compatible iterator type + +## Parameters + +`i` (in) : an input in UBJSON format convertible to an input adapter + +`first` (in) : iterator to the start of the input + +`last` (in) : iterator to the end of the input + +`strict` (in) : whether to expect the input to be consumed until EOF (`true` by default) + +`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default) + +## Return value + +deserialized JSON value; in case of a parse error and `allow_exceptions` set to `false`, the return value will be `value_t::discarded`. The latter can be checked with [`is_discarded`](https://json.nlohmann.me/api/basic_json/is_discarded/index.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [parse_error.110](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error110) if the given input ends prematurely or the end of the file was not reached when `strict` was set to true +- Throws [parse_error.112](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error112) if a parse error occurs +- Throws [parse_error.113](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error113) if a string could not be parsed successfully +- Throws [out_of_range.408](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range408) if the size of an optimized container or n-dimensional array cannot be represented by `std::size_t` + +## Complexity + +Linear in the size of the input. + +## Examples + +Example + +The example shows the deserialization of a byte vector in UBJSON format to a JSON value. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, + 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D + }; + + // deserialize it with UBJSON + json j = json::from_ubjson(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` + +## See also + +- [to_ubjson](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) create a UBJSON serialization of a JSON value +- [from_cbor](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) create a JSON value from an input in CBOR format +- [from_msgpack](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md) create a JSON value from an input in MessagePack format +- [from_bson](https://json.nlohmann.me/api/basic_json/from_bson/index.md) create a JSON value from an input in BSON format +- [from_bjdata](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md) create a JSON value from an input in BJData format + +## Version history + +- Added in version 3.1.0. +- Added `allow_exceptions` parameter in version 3.2.0. + +Deprecation + +- Overload (2) replaces calls to `from_ubjson` with a pointer and a length as first two parameters, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_ubjson(ptr, len, ...);` with `from_ubjson(ptr, ptr+len, ...);`. +- Overload (2) replaces calls to `from_ubjson` with a pair of iterators as their first parameter, which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `from_ubjson({ptr, ptr+len}, ...);` with `from_ubjson(ptr, ptr+len, ...);`. + +You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated function. diff --git a/api/basic_json/front.md b/api/basic_json/front.md new file mode 100644 index 000000000..b5fea1135 --- /dev/null +++ b/api/basic_json/front.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json::front + +```cpp +reference front(); +const_reference front() const; +``` + +Returns a reference to the first element in the container. For a JSON container `#!cpp c`, the expression +`#!cpp c.front()` is equivalent to `#!cpp *c.begin()`. + +## Return value + +In the case of a structured type (array or object), a reference to the first element is returned. In the case of number, +string, boolean, or binary values, a reference to the value is returned. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +If the JSON value is `#!json null`, exception +[`invalid_iterator.214`](../../home/exceptions.md#jsonexceptioninvalid_iterator214) is thrown. + +## Complexity + +Constant. + +## Notes + +!!! info "Precondition" + + The array or object must not be empty. Calling `front` on an empty array or object yields undefined behavior. + +## Examples + +??? example + + The following code shows an example for `front()`. + + ```cpp + --8<-- "examples/front.cpp" + ``` + + Output: + + ```json + --8<-- "examples/front.output" + ``` + +## See also + +- [back](back.md) to access the last element + +## Version history + +- Added in version 1.0.0. +- Adjusted code to return reference to binary values in version 3.8.0. diff --git a/api/basic_json/front/index.html b/api/basic_json/front/index.html index 535f9fcee..f60c694a8 100644 --- a/api/basic_json/front/index.html +++ b/api/basic_json/front/index.html @@ -35,4 +35,4 @@ 1 1 "Hello, world" -

See also

  • back to access the last element

Version history

  • Added in version 1.0.0.
  • Adjusted code to return reference to binary values in version 3.8.0.
\ No newline at end of file +

See also

  • back to access the last element

Version history

  • Added in version 1.0.0.
  • Adjusted code to return reference to binary values in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/front/index.md b/api/basic_json/front/index.md new file mode 100644 index 000000000..08df5dcfc --- /dev/null +++ b/api/basic_json/front/index.md @@ -0,0 +1,88 @@ +# nlohmann::basic_json::front + +``` +reference front(); +const_reference front() const; +``` + +Returns a reference to the first element in the container. For a JSON container `c`, the expression `c.front()` is equivalent to `*c.begin()`. + +## Return value + +In the case of a structured type (array or object), a reference to the first element is returned. In the case of number, string, boolean, or binary values, a reference to the value is returned. + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +If the JSON value is `null`, exception [`invalid_iterator.214`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator214) is thrown. + +## Complexity + +Constant. + +## Notes + +Precondition + +The array or object must not be empty. Calling `front` on an empty array or object yields undefined behavior. + +## Examples + +Example + +The following code shows an example for `front()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call front() + //std::cout << j_null.front() << '\n'; // would throw + std::cout << j_boolean.front() << '\n'; + std::cout << j_number_integer.front() << '\n'; + std::cout << j_number_float.front() << '\n'; + std::cout << j_object.front() << '\n'; + //std::cout << j_object_empty.front() << '\n'; // undefined behavior + std::cout << j_array.front() << '\n'; + //std::cout << j_array_empty.front() << '\n'; // undefined behavior + std::cout << j_string.front() << '\n'; +} +``` + +Output: + +``` +true +17 +23.42 +1 +1 +"Hello, world" +``` + +## See also + +- [back](https://json.nlohmann.me/api/basic_json/back/index.md) to access the last element + +## Version history + +- Added in version 1.0.0. +- Adjusted code to return reference to binary values in version 3.8.0. diff --git a/api/basic_json/get.md b/api/basic_json/get.md new file mode 100644 index 000000000..adf63b8a7 --- /dev/null +++ b/api/basic_json/get.md @@ -0,0 +1,164 @@ +# nlohmann::basic_json::get + +```cpp +// (1) +template +ValueType get() const noexcept( + noexcept(JSONSerializer::from_json( + std::declval(), std::declval()))); + +// (2) +template +BasicJsonType get() const; + +// (3) +template +PointerType get_ptr(); + +template +constexpr const PointerType get_ptr() const noexcept; +``` + +1. Explicit type conversion between the JSON value and a compatible value which is + [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and + [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). The value is converted by + calling the `json_serializer` `from_json()` method. + + The function is equivalent to executing + ```cpp + ValueType ret; + JSONSerializer::from_json(*this, ret); + return ret; + ``` + + This overload is chosen if: + + - `ValueType` is not `basic_json`, + - `json_serializer` has a `from_json()` method of the form + `void from_json(const basic_json&, ValueType&)`, and + - `json_serializer` does not have a `from_json()` method of the form + `ValueType from_json(const basic_json&)` + + If the type is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and + **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible), the value is + converted by calling the `json_serializer` `from_json()` method. + + The function is then equivalent to executing + ```cpp + return JSONSerializer::from_json(*this); + ``` + + This overload is chosen if: + + - `ValueType` is not `basic_json` and + - `json_serializer` has a `from_json()` method of the form + `ValueType from_json(const basic_json&)` + + If `json_serializer` has both overloads of `from_json()`, the latter one is chosen. + +2. Overload for `basic_json` specializations. The function is equivalent to executing + ```cpp + return *this; + ``` + +3. Explicit pointer access to the internally stored JSON value. No copies are made. + +## Template parameters + +`ValueType` +: the value type to return + +`BasicJsonType` +: a specialization of `basic_json` + +`PointerType` +: pointer type; must be a pointer to [`array_t`](array_t.md), [`object_t`](object_t.md), [`string_t`](string_t.md), + [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or + [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md). + Other types will not compile. + +## Return value + +1. copy of the JSON value, converted to `ValueType` +2. a copy of `#!cpp *this`, converted into `BasicJsonType` +3. pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `#!cpp nullptr` + otherwise + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Complexity + +Depends on the `json_serializer::from_json()` implementation for overloads (1) and (2); constant for +overload (3). + +## Notes + +!!! danger "Undefined behavior for pointers" + + Writing data to the pointee (overload 3) of the result yields an undefined state. + +!!! danger "Undefined behavior for numeric conversions" + + Conversions between numeric types are performed by the corresponding + `from_json()` implementation using the target C++ type. When converting + between numeric types, the library does not check whether the source + value is representable by the target type. + + If the source value is outside the range of the target type, the behavior + is the same as the corresponding C++ conversion. In particular, converting + a floating-point value to an integer type that cannot represent the value + results in undefined behavior. + + See [Number conversion](../../features/types/number_handling.md#number-conversion) + for more information. + +## Examples + +??? example + + The example below shows several conversions from JSON values + to other types. There a few things to note: (1) Floating-point numbers can + be converted to integers, (2) A JSON array can be converted to a standard + `std::vector`, (3) A JSON object can be converted to C++ + associative containers such as `std::unordered_map`. + + ```cpp + --8<-- "examples/get__ValueType_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get__ValueType_const.output" + ``` + +??? example + + The example below shows how pointers to internal values of a JSON value can be requested. Note that no type + conversions are made and a `#cpp nullptr` is returned if the value and the requested pointer type does not match. + + ```cpp + --8<-- "examples/get__PointerType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get__PointerType.output" + ``` + +## See also + +- [get_to](get_to.md) convert and write into a passed value +- [get_ptr](get_ptr.md) get a pointer to the stored value +- [get_ref](get_ref.md) get a reference to the stored value +- [operator ValueType](operator_ValueType.md) get a value via implicit conversion +- [Converting values](../../features/conversions.md) - the type conversions article + +## Version history + +1. Since version 2.1.0. +2. Since version 2.1.0. Extended to work with other specializations of `basic_json` in version 3.2.0. +3. Since version 1.0.0. diff --git a/api/basic_json/get/index.html b/api/basic_json/get/index.html index c5b743a38..71fa9dc67 100644 --- a/api/basic_json/get/index.html +++ b/api/basic_json/get/index.html @@ -103,4 +103,4 @@ }

Output:

17 17 17 17
 true
-

See also

Version history

  1. Since version 2.1.0.
  2. Since version 2.1.0. Extended to work with other specializations of basic_json in version 3.2.0.
  3. Since version 1.0.0.
\ No newline at end of file +

See also

Version history

  1. Since version 2.1.0.
  2. Since version 2.1.0. Extended to work with other specializations of basic_json in version 3.2.0.
  3. Since version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/get/index.md b/api/basic_json/get/index.md new file mode 100644 index 000000000..68cc17948 --- /dev/null +++ b/api/basic_json/get/index.md @@ -0,0 +1,219 @@ +# nlohmann::basic_json::get + +``` +// (1) +template +ValueType get() const noexcept( + noexcept(JSONSerializer::from_json( + std::declval(), std::declval()))); + +// (2) +template +BasicJsonType get() const; + +// (3) +template +PointerType get_ptr(); + +template +constexpr const PointerType get_ptr() const noexcept; +``` + +1. Explicit type conversion between the JSON value and a compatible value which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). The value is converted by calling the `json_serializer` `from_json()` method. + + The function is equivalent to executing + + ``` + ValueType ret; + JSONSerializer::from_json(*this, ret); + return ret; + ``` + + This overload is chosen if: + + - `ValueType` is not `basic_json`, + - `json_serializer` has a `from_json()` method of the form `void from_json(const basic_json&, ValueType&)`, and + - `json_serializer` does not have a `from_json()` method of the form `ValueType from_json(const basic_json&)` + + If the type is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible) and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible), the value is converted by calling the `json_serializer` `from_json()` method. + + The function is then equivalent to executing + + ``` + return JSONSerializer::from_json(*this); + ``` + + This overload is chosen if: + + - `ValueType` is not `basic_json` and + - `json_serializer` has a `from_json()` method of the form `ValueType from_json(const basic_json&)` + + If `json_serializer` has both overloads of `from_json()`, the latter one is chosen. + +1. Overload for `basic_json` specializations. The function is equivalent to executing + + ``` + return *this; + ``` + +1. Explicit pointer access to the internally stored JSON value. No copies are made. + +## Template parameters + +`ValueType` : the value type to return + +`BasicJsonType` : a specialization of `basic_json` + +`PointerType` : pointer type; must be a pointer to [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md), [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md), [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md), [`boolean_t`](https://json.nlohmann.me/api/basic_json/boolean_t/index.md), [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md), or [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md), [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md), or [`binary_t`](https://json.nlohmann.me/api/basic_json/binary_t/index.md). Other types will not compile. + +## Return value + +1. copy of the JSON value, converted to `ValueType` +1. a copy of `*this`, converted into `BasicJsonType` +1. pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `nullptr` otherwise + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Complexity + +Depends on the `json_serializer::from_json()` implementation for overloads (1) and (2); constant for overload (3). + +## Notes + +Undefined behavior for pointers + +Writing data to the pointee (overload 3) of the result yields an undefined state. + +Undefined behavior for numeric conversions + +Conversions between numeric types are performed by the corresponding `from_json()` implementation using the target C++ type. When converting between numeric types, the library does not check whether the source value is representable by the target type. + +If the source value is outside the range of the target type, the behavior is the same as the corresponding C++ conversion. In particular, converting a floating-point value to an integer type that cannot represent the value results in undefined behavior. + +See [Number conversion](https://json.nlohmann.me/features/types/number_handling/#number-conversion) for more information. + +## Examples + +Example + +The example below shows several conversions from JSON values to other types. There a few things to note: (1) Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard `std::vector`, (3) A JSON object can be converted to C++ associative containers such as `std::unordered_map`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + // use explicit conversions + auto v1 = json_types["boolean"].get(); + auto v2 = json_types["number"]["integer"].get(); + auto v3 = json_types["number"]["integer"].get(); + auto v4 = json_types["number"]["floating-point"].get(); + auto v5 = json_types["number"]["floating-point"].get(); + auto v6 = json_types["string"].get(); + auto v7 = json_types["array"].get>(); + auto v8 = json_types.get>(); + + // print the conversion results + std::cout << v1 << '\n'; + std::cout << v2 << ' ' << v3 << '\n'; + std::cout << v4 << ' ' << v5 << '\n'; + std::cout << v6 << '\n'; + + for (auto i : v7) + { + std::cout << i << ' '; + } + std::cout << "\n\n"; + + for (auto i : v8) + { + std::cout << i.first << ": " << i.second << '\n'; + } +} +``` + +Output: + +``` +1 +42 42 +17.23 17 +Hello, world! +1 2 3 4 5 + +string: "Hello, world!" +number: {"floating-point":17.23,"integer":42} +null: null +boolean: true +array: [1,2,3,4,5] +``` + +Example + +The example below shows how pointers to internal values of a JSON value can be requested. Note that no type conversions are made and a `#cpp nullptr` is returned if the value and the requested pointer type does not match. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON number + json value = 17; + + // explicitly getting pointers + auto p1 = value.get(); + auto p2 = value.get(); + auto p3 = value.get(); + auto p4 = value.get(); + auto p5 = value.get(); + + // print the pointees + std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n'; + std::cout << std::boolalpha << (p5 == nullptr) << '\n'; +} +``` + +Output: + +``` +17 17 17 17 +true +``` + +## See also + +- [get_to](https://json.nlohmann.me/api/basic_json/get_to/index.md) convert and write into a passed value +- [get_ptr](https://json.nlohmann.me/api/basic_json/get_ptr/index.md) get a pointer to the stored value +- [get_ref](https://json.nlohmann.me/api/basic_json/get_ref/index.md) get a reference to the stored value +- [operator ValueType](https://json.nlohmann.me/api/basic_json/operator_ValueType/index.md) get a value via implicit conversion +- [Converting values](https://json.nlohmann.me/features/conversions/index.md) - the type conversions article + +## Version history + +1. Since version 2.1.0. +1. Since version 2.1.0. Extended to work with other specializations of `basic_json` in version 3.2.0. +1. Since version 1.0.0. diff --git a/api/basic_json/get_allocator.md b/api/basic_json/get_allocator.md new file mode 100644 index 000000000..07a4d8456 --- /dev/null +++ b/api/basic_json/get_allocator.md @@ -0,0 +1,31 @@ +# nlohmann::basic_json::get_allocator + +```cpp +static allocator_type get_allocator(); +``` + +Returns the allocator associated with the container. + +## Return value + +associated allocator + +## Examples + +??? example + + The example shows how `get_allocator()` is used to created `json` values. + + ```cpp + --8<-- "examples/get_allocator.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_allocator.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/get_allocator/index.html b/api/basic_json/get_allocator/index.html index 2f9888bee..03d5a17cc 100644 --- a/api/basic_json/get_allocator/index.html +++ b/api/basic_json/get_allocator/index.html @@ -18,4 +18,4 @@ traits_t::deallocate(alloc, j, 1); }

Output:

"Hello, world!"
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/get_allocator/index.md b/api/basic_json/get_allocator/index.md new file mode 100644 index 000000000..4e31f7732 --- /dev/null +++ b/api/basic_json/get_allocator/index.md @@ -0,0 +1,48 @@ +# nlohmann::basic_json::get_allocator + +``` +static allocator_type get_allocator(); +``` + +Returns the allocator associated with the container. + +## Return value + +associated allocator + +## Examples + +Example + +The example shows how `get_allocator()` is used to created `json` values. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + auto alloc = json::get_allocator(); + using traits_t = std::allocator_traits; + + json* j = traits_t::allocate(alloc, 1); + traits_t::construct(alloc, j, "Hello, world!"); + + std::cout << *j << std::endl; + + traits_t::destroy(alloc, j); + traits_t::deallocate(alloc, j, 1); +} +``` + +Output: + +``` +"Hello, world!" +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/get_binary.md b/api/basic_json/get_binary.md new file mode 100644 index 000000000..569e72274 --- /dev/null +++ b/api/basic_json/get_binary.md @@ -0,0 +1,50 @@ +# nlohmann::basic_json::get_binary + +```cpp +binary_t& get_binary(); + +const binary_t& get_binary() const; +``` + +Returns a reference to the stored binary value. + +## Return value + +Reference to binary value. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if the value is not binary + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows how to query a binary value. + + ```cpp + --8<-- "examples/get_binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_binary.output" + ``` + +## See also + +- [get](get.md) get a value (explicit conversion) +- [get_ref](get_ref.md) get a reference to the stored value + +## Version history + +- Added in version 3.8.0. diff --git a/api/basic_json/get_binary/index.html b/api/basic_json/get_binary/index.html index 6ec3039f3..260e09842 100644 --- a/api/basic_json/get_binary/index.html +++ b/api/basic_json/get_binary/index.html @@ -18,4 +18,4 @@ std::cout << "type: " << j.type_name() << ", subtype: " << j.get_binary().subtype() << std::endl; }

Output:

type: binary, subtype: 42
-

See also

  • get get a value (explicit conversion)
  • get_ref get a reference to the stored value

Version history

  • Added in version 3.8.0.
\ No newline at end of file +

See also

  • get get a value (explicit conversion)
  • get_ref get a reference to the stored value

Version history

  • Added in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/get_binary/index.md b/api/basic_json/get_binary/index.md new file mode 100644 index 000000000..8b7dc443f --- /dev/null +++ b/api/basic_json/get_binary/index.md @@ -0,0 +1,65 @@ +# nlohmann::basic_json::get_binary + +``` +binary_t& get_binary(); + +const binary_t& get_binary() const; +``` + +Returns a reference to the stored binary value. + +## Return value + +Reference to binary value. + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +Throws [`type_error.302`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error302) if the value is not binary + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows how to query a binary value. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a binary vector + std::vector vec = {0xCA, 0xFE, 0xBA, 0xBE}; + + // create a binary JSON value with subtype 42 + json j = json::binary(vec, 42); + + // output type and subtype + std::cout << "type: " << j.type_name() << ", subtype: " << j.get_binary().subtype() << std::endl; +} +``` + +Output: + +``` +type: binary, subtype: 42 +``` + +## See also + +- [get](https://json.nlohmann.me/api/basic_json/get/index.md) get a value (explicit conversion) +- [get_ref](https://json.nlohmann.me/api/basic_json/get_ref/index.md) get a reference to the stored value + +## Version history + +- Added in version 3.8.0. diff --git a/api/basic_json/get_ptr.md b/api/basic_json/get_ptr.md new file mode 100644 index 000000000..7c000f1ac --- /dev/null +++ b/api/basic_json/get_ptr.md @@ -0,0 +1,94 @@ +# nlohmann::basic_json::get_ptr + +```cpp +template +PointerType get_ptr() noexcept; + +template +constexpr const PointerType get_ptr() const noexcept; +``` + +Implicit pointer access to the internally stored JSON value. No copies are made. + +## Template parameters + +`PointerType` +: pointer type; must be a pointer to [`array_t`](array_t.md), [`object_t`](object_t.md), [`string_t`](string_t.md), + [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or + [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md). + Other types will not compile. + +## Return value + +pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `#!cpp nullptr` +otherwise + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +!!! danger "Undefined behavior" + + The pointer becomes invalid if the underlying JSON object changes. + + Consider the following example code where the pointer `ptr` changes after the array is resized. As a result, + reading or writing to `ptr` after the array change would be undefined behavior. The address of the first array + element changes, because the underlying `std::vector` is resized after adding a fifth element. + + ```cpp + #include + #include + + using json = nlohmann::json; + + int main() + { + json j = {1, 2, 3, 4}; + auto* ptr = j[0].get_ptr(); + std::cout << "value at " << ptr << " is " << *ptr << std::endl; + + j.push_back(5); + + ptr = j[0].get_ptr(); + std::cout << "value at " << ptr << " is " << *ptr << std::endl; + } + ``` + + Output: + + ``` + value at 0x6000012fc1c8 is 1 + value at 0x6000029fc088 is 1 + ``` + +## Examples + +??? example + + The example below shows how pointers to internal values of a JSON value can be requested. Note that no type + conversions are made and a `#!cpp nullptr` is returned if the value and the requested pointer type does not match. + + ```cpp + --8<-- "examples/get_ptr.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_ptr.output" + ``` + +## See also + +- [get_ref()](get_ref.md) get a reference value + +## Version history + +- Added in version 1.0.0. +- Extended to binary types in version 3.8.0. diff --git a/api/basic_json/get_ptr/index.html b/api/basic_json/get_ptr/index.html index 837d800be..d6422e92c 100644 --- a/api/basic_json/get_ptr/index.html +++ b/api/basic_json/get_ptr/index.html @@ -44,4 +44,4 @@ value at 0x6000029fc088 is 1 }

Output:

17 17 17 17
 true
-

See also

Version history

  • Added in version 1.0.0.
  • Extended to binary types in version 3.8.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
  • Extended to binary types in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/get_ptr/index.md b/api/basic_json/get_ptr/index.md new file mode 100644 index 000000000..486d13898 --- /dev/null +++ b/api/basic_json/get_ptr/index.md @@ -0,0 +1,107 @@ +# nlohmann::basic_json::get_ptr + +``` +template +PointerType get_ptr() noexcept; + +template +constexpr const PointerType get_ptr() const noexcept; +``` + +Implicit pointer access to the internally stored JSON value. No copies are made. + +## Template parameters + +`PointerType` : pointer type; must be a pointer to [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md), [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md), [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md), [`boolean_t`](https://json.nlohmann.me/api/basic_json/boolean_t/index.md), [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md), or [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md), [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md), or [`binary_t`](https://json.nlohmann.me/api/basic_json/binary_t/index.md). Other types will not compile. + +## Return value + +pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; `nullptr` otherwise + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +Undefined behavior + +The pointer becomes invalid if the underlying JSON object changes. + +Consider the following example code where the pointer `ptr` changes after the array is resized. As a result, reading or writing to `ptr` after the array change would be undefined behavior. The address of the first array element changes, because the underlying `std::vector` is resized after adding a fifth element. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j = {1, 2, 3, 4}; + auto* ptr = j[0].get_ptr(); + std::cout << "value at " << ptr << " is " << *ptr << std::endl; + + j.push_back(5); + + ptr = j[0].get_ptr(); + std::cout << "value at " << ptr << " is " << *ptr << std::endl; +} +``` + +Output: + +``` +value at 0x6000012fc1c8 is 1 +value at 0x6000029fc088 is 1 +``` + +## Examples + +Example + +The example below shows how pointers to internal values of a JSON value can be requested. Note that no type conversions are made and a `nullptr` is returned if the value and the requested pointer type does not match. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON number + json value = 17; + + // explicitly getting pointers + auto p1 = value.get_ptr(); + auto p2 = value.get_ptr(); + auto p3 = value.get_ptr(); + auto p4 = value.get_ptr(); + auto p5 = value.get_ptr(); + + // print the pointees + std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n'; + std::cout << std::boolalpha << (p5 == nullptr) << '\n'; +} +``` + +Output: + +``` +17 17 17 17 +true +``` + +## See also + +- [get_ref()](https://json.nlohmann.me/api/basic_json/get_ref/index.md) get a reference value + +## Version history + +- Added in version 1.0.0. +- Extended to binary types in version 3.8.0. diff --git a/api/basic_json/get_ref.md b/api/basic_json/get_ref.md new file mode 100644 index 000000000..73b20b0e0 --- /dev/null +++ b/api/basic_json/get_ref.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::get_ref + +```cpp +template +ReferenceType get_ref(); + +template +const ReferenceType get_ref() const; +``` + +Implicit reference access to the internally stored JSON value. No copies are made. + +## Template parameters + +`ReferenceType` +: reference type; must be a reference to [`array_t`](array_t.md), [`object_t`](object_t.md), + [`string_t`](string_t.md), [`boolean_t`](boolean_t.md), [`number_integer_t`](number_integer_t.md), or + [`number_unsigned_t`](number_unsigned_t.md), [`number_float_t`](number_float_t.md), or [`binary_t`](binary_t.md). + Enforced by a static assertion. + +## Return value + +reference to the internally stored JSON value if the requested reference type fits to the JSON value; throws +[`type_error.303`](../../home/exceptions.md#jsonexceptiontype_error303) otherwise + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +Throws [`type_error.303`](../../home/exceptions.md#jsonexceptiontype_error303) if the requested reference type does not +match the stored JSON value type; example: `"incompatible ReferenceType for get_ref, actual type is binary"`. + +## Complexity + +Constant. + +## Notes + +!!! danger "Undefined behavior" + + The reference becomes invalid if the underlying JSON object changes. + +## Examples + +??? example + + The example shows several calls to `get_ref()`. + + ```cpp + --8<-- "examples/get_ref.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_ref.output" + ``` + +## See also + +- [get_ptr()](get_ptr.md) get a pointer value + +## Version history + +- Added in version 1.1.0. +- Extended to binary types in version 3.8.0. diff --git a/api/basic_json/get_ref/index.html b/api/basic_json/get_ref/index.html index 60d810839..f20bd5911 100644 --- a/api/basic_json/get_ref/index.html +++ b/api/basic_json/get_ref/index.html @@ -32,4 +32,4 @@ }

Output:

17 17
 [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number
-

See also

Version history

  • Added in version 1.1.0.
  • Extended to binary types in version 3.8.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.1.0.
  • Extended to binary types in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/get_ref/index.md b/api/basic_json/get_ref/index.md new file mode 100644 index 000000000..2056212a2 --- /dev/null +++ b/api/basic_json/get_ref/index.md @@ -0,0 +1,89 @@ +# nlohmann::basic_json::get_ref + +``` +template +ReferenceType get_ref(); + +template +const ReferenceType get_ref() const; +``` + +Implicit reference access to the internally stored JSON value. No copies are made. + +## Template parameters + +`ReferenceType` : reference type; must be a reference to [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md), [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md), [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md), [`boolean_t`](https://json.nlohmann.me/api/basic_json/boolean_t/index.md), [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md), or [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md), [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md), or [`binary_t`](https://json.nlohmann.me/api/basic_json/binary_t/index.md). Enforced by a static assertion. + +## Return value + +reference to the internally stored JSON value if the requested reference type fits to the JSON value; throws [`type_error.303`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error303) otherwise + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +Throws [`type_error.303`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error303) if the requested reference type does not match the stored JSON value type; example: `"incompatible ReferenceType for get_ref, actual type is binary"`. + +## Complexity + +Constant. + +## Notes + +Undefined behavior + +The reference becomes invalid if the underlying JSON object changes. + +## Examples + +Example + +The example shows several calls to `get_ref()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON number + json value = 17; + + // explicitly getting references + auto r1 = value.get_ref(); + auto r2 = value.get_ref(); + + // print the values + std::cout << r1 << ' ' << r2 << '\n'; + + // incompatible type throws exception + try + { + auto r3 = value.get_ref(); + } + catch (const json::type_error& ex) + { + std::cout << ex.what() << '\n'; + } +} +``` + +Output: + +``` +17 17 +[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number +``` + +## See also + +- [get_ptr()](https://json.nlohmann.me/api/basic_json/get_ptr/index.md) get a pointer value + +## Version history + +- Added in version 1.1.0. +- Extended to binary types in version 3.8.0. diff --git a/api/basic_json/get_to.md b/api/basic_json/get_to.md new file mode 100644 index 000000000..8334ba5cf --- /dev/null +++ b/api/basic_json/get_to.md @@ -0,0 +1,69 @@ +# nlohmann::basic_json::get_to + +```cpp +template +ValueType& get_to(ValueType& v) const noexcept( + noexcept(JSONSerializer::from_json( + std::declval(), v))); +``` + +Explicit type conversion between the JSON value and a compatible value. The value is filled into the input parameter by +calling the `json_serializer` `from_json()` method. + +The function is equivalent to executing +```cpp +ValueType v; +JSONSerializer::from_json(*this, v); +``` + +This overload is chosen if: + +- `ValueType` is not `basic_json`, +- `json_serializer` has a `from_json()` method of the form `void from_json(const basic_json&, ValueType&)` + +## Template parameters + +`ValueType` +: the value type to return + +## Return value + +the input parameter, allowing chaining calls + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Complexity + +Depends on the `json_serializer::from_json()` implementation. + +## Examples + +??? example + + The example below shows several conversions from JSON values to other types. There a few things to note: (1) + Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard + `#!cpp std::vector`, (3) A JSON object can be converted to C++ associative containers such as + `#cpp std::unordered_map`. + + ```cpp + --8<-- "examples/get_to.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_to.output" + ``` + +## See also + +- [get](get.md) get a value (explicit conversion) +- [get_ref](get_ref.md) get a reference to the stored value +- [get_ptr](get_ptr.md) get a pointer to the stored value +- [Converting values](../../features/conversions.md) - the type conversions article + +## Version history + +- Since version 3.3.0. diff --git a/api/basic_json/get_to/index.html b/api/basic_json/get_to/index.html index e7e57cc67..4b79fe7e8 100644 --- a/api/basic_json/get_to/index.html +++ b/api/basic_json/get_to/index.html @@ -74,4 +74,4 @@ null: null boolean: true array: [1,2,3,4,5] -

See also

  • get get a value (explicit conversion)
  • get_ref get a reference to the stored value
  • get_ptr get a pointer to the stored value
  • Converting values - the type conversions article

Version history

  • Since version 3.3.0.
\ No newline at end of file +

See also

  • get get a value (explicit conversion)
  • get_ref get a reference to the stored value
  • get_ptr get a pointer to the stored value
  • Converting values - the type conversions article

Version history

  • Since version 3.3.0.
\ No newline at end of file diff --git a/api/basic_json/get_to/index.md b/api/basic_json/get_to/index.md new file mode 100644 index 000000000..fc5bcef7c --- /dev/null +++ b/api/basic_json/get_to/index.md @@ -0,0 +1,133 @@ +# nlohmann::basic_json::get_to + +``` +template +ValueType& get_to(ValueType& v) const noexcept( + noexcept(JSONSerializer::from_json( + std::declval(), v))); +``` + +Explicit type conversion between the JSON value and a compatible value. The value is filled into the input parameter by calling the `json_serializer` `from_json()` method. + +The function is equivalent to executing + +``` +ValueType v; +JSONSerializer::from_json(*this, v); +``` + +This overload is chosen if: + +- `ValueType` is not `basic_json`, +- `json_serializer` has a `from_json()` method of the form `void from_json(const basic_json&, ValueType&)` + +## Template parameters + +`ValueType` : the value type to return + +## Return value + +the input parameter, allowing chaining calls + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Complexity + +Depends on the `json_serializer::from_json()` implementation. + +## Examples + +Example + +The example below shows several conversions from JSON values to other types. There a few things to note: (1) Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard `std::vector`, (3) A JSON object can be converted to C++ associative containers such as `#cpp std::unordered_map`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + bool v1; + int v2; + short v3; + float v4; + int v5; + std::string v6; + std::vector v7; + std::unordered_map v8; + + // use explicit conversions + json_types["boolean"].get_to(v1); + json_types["number"]["integer"].get_to(v2); + json_types["number"]["integer"].get_to(v3); + json_types["number"]["floating-point"].get_to(v4); + json_types["number"]["floating-point"].get_to(v5); + json_types["string"].get_to(v6); + json_types["array"].get_to(v7); + json_types.get_to(v8); + + // print the conversion results + std::cout << v1 << '\n'; + std::cout << v2 << ' ' << v3 << '\n'; + std::cout << v4 << ' ' << v5 << '\n'; + std::cout << v6 << '\n'; + + for (auto i : v7) + { + std::cout << i << ' '; + } + std::cout << "\n\n"; + + for (auto i : v8) + { + std::cout << i.first << ": " << i.second << '\n'; + } +} +``` + +Output: + +``` +1 +42 42 +17.23 17 +Hello, world! +1 2 3 4 5 + +string: "Hello, world!" +number: {"floating-point":17.23,"integer":42} +null: null +boolean: true +array: [1,2,3,4,5] +``` + +## See also + +- [get](https://json.nlohmann.me/api/basic_json/get/index.md) get a value (explicit conversion) +- [get_ref](https://json.nlohmann.me/api/basic_json/get_ref/index.md) get a reference to the stored value +- [get_ptr](https://json.nlohmann.me/api/basic_json/get_ptr/index.md) get a pointer to the stored value +- [Converting values](https://json.nlohmann.me/features/conversions/index.md) - the type conversions article + +## Version history + +- Since version 3.3.0. diff --git a/api/basic_json/index.html b/api/basic_json/index.html index 28fb59bcb..835a5de99 100644 --- a/api/basic_json/index.html +++ b/api/basic_json/index.html @@ -78,4 +78,4 @@ "pi": 3.141, "size": 8 } -

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/index.md b/api/basic_json/index.md new file mode 100644 index 000000000..5d93fee1f --- /dev/null +++ b/api/basic_json/index.md @@ -0,0 +1,383 @@ +# nlohmann::basic_json + +Defined in header `` + +``` +template< + template class ObjectType = std::map, + template class ArrayType = std::vector, + class StringType = std::string, + class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = adl_serializer, + class BinaryType = std::vector, + class CustomBaseClass = void +> +class basic_json; +``` + +## Template parameters + +| Template parameter | Description | Derived type | +| -------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `ObjectType` | type for JSON objects | [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md) | +| `ArrayType` | type for JSON arrays | [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md) | +| `StringType` | type for JSON strings and object keys | [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) | +| `BooleanType` | type for JSON booleans | [`boolean_t`](https://json.nlohmann.me/api/basic_json/boolean_t/index.md) | +| `NumberIntegerType` | type for JSON integer numbers | [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) | +| `NumberUnsignedType` | type for JSON unsigned integer numbers | [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) | +| `NumberFloatType` | type for JSON floating-point numbers | [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) | +| `AllocatorType` | type of the allocator to use | | +| `JSONSerializer` | the serializer to resolve internal calls to `to_json()` and `from_json()` | [`json_serializer`](https://json.nlohmann.me/api/basic_json/json_serializer/index.md) | +| `BinaryType` | type for binary arrays | [`binary_t`](https://json.nlohmann.me/api/basic_json/binary_t/index.md) | +| `CustomBaseClass` | extension point for user code | [`json_base_class_t`](https://json.nlohmann.me/api/basic_json/json_base_class_t/index.md) | + +## Specializations + +- [**json**](https://json.nlohmann.me/api/json/index.md) - default specialization +- [**ordered_json**](https://json.nlohmann.me/api/ordered_json/index.md) - a specialization that maintains the insertion order of object keys + +## Iterator invalidation + +All operations that add values to an **array** ([`push_back`](https://json.nlohmann.me/api/basic_json/push_back/index.md) , [`operator+=`](https://json.nlohmann.me/api/basic_json/operator%2B%3D/index.md), [`emplace_back`](https://json.nlohmann.me/api/basic_json/emplace_back/index.md), [`insert`](https://json.nlohmann.me/api/basic_json/insert/index.md), and [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) for a non-existing index) can yield a reallocation, in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. + +For [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), also all operations that add a value to an **object** ([`push_back`](https://json.nlohmann.me/api/basic_json/push_back/index.md), [`operator+=`](https://json.nlohmann.me/api/basic_json/operator%2B%3D/index.md), [`emplace`](https://json.nlohmann.me/api/basic_json/emplace/index.md), [`insert`](https://json.nlohmann.me/api/basic_json/insert/index.md), [`update`](https://json.nlohmann.me/api/basic_json/update/index.md), and [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) for a non-existing key) can yield a reallocation, in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. + +## Requirements + +The class satisfies the following concept requirements: + +### Basic + +- [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): JSON values can be default-constructed. The result will be a JSON null value. +- [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): A JSON value can be constructed from an rvalue argument. +- [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): A JSON value can be copy-constructed from an lvalue expression. +- [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): A JSON value can be assigned from an rvalue argument. +- [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): A JSON value can be copy-assigned from an lvalue expression. +- [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): JSON values can be destructed. + +### Layout + +- [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): JSON values have [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): All non-static data members are private and standard layout types, the class has no virtual functions or (virtual) base classes. + +### Library-wide + +- [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): JSON values can be compared with `==`, see [`operator==`](https://json.nlohmann.me/api/basic_json/operator_eq/index.md). +- [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): JSON values can be compared with `<`, see [`operator<`](https://json.nlohmann.me/api/basic_json/operator_le/index.md). +- [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of other compatible types, using unqualified function `swap`. +- [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): JSON values can be compared against `std::nullptr_t` objects which are used to model the `null` value. + +### Container + +- [Container](https://en.cppreference.com/w/cpp/named_req/Container): JSON values can be used like STL containers and provide iterator access. +- [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer): JSON values can be used like STL containers and provide reverse iterator access. + +## Member types + +- [**adl_serializer**](https://json.nlohmann.me/api/adl_serializer/index.md) - the default serializer +- [**value_t**](https://json.nlohmann.me/api/basic_json/value_t/index.md) - the JSON type enumeration +- [**json_pointer**](https://json.nlohmann.me/api/json_pointer/index.md) - JSON Pointer implementation +- [**json_serializer**](https://json.nlohmann.me/api/basic_json/json_serializer/index.md) - type of the serializer to for conversions from/to JSON +- [**error_handler_t**](https://json.nlohmann.me/api/basic_json/error_handler_t/index.md) - type to choose behavior on decoding errors +- [**cbor_tag_handler_t**](https://json.nlohmann.me/api/basic_json/cbor_tag_handler_t/index.md) - type to choose how to handle CBOR tags +- **initializer_list_t** - type for initializer lists of `basic_json` values +- [**input_format_t**](https://json.nlohmann.me/api/basic_json/input_format_t/index.md) - type to choose the format to parse +- [**json_sax_t**](https://json.nlohmann.me/api/json_sax/index.md) - type for SAX events + +### Exceptions + +- [**exception**](https://json.nlohmann.me/api/basic_json/exception/index.md) - general exception of the `basic_json` class + - [**parse_error**](https://json.nlohmann.me/api/basic_json/parse_error/index.md) - exception indicating a parse error + - [**invalid_iterator**](https://json.nlohmann.me/api/basic_json/invalid_iterator/index.md) - exception indicating errors with iterators + - [**type_error**](https://json.nlohmann.me/api/basic_json/type_error/index.md) - exception indicating executing a member function with a wrong type + - [**out_of_range**](https://json.nlohmann.me/api/basic_json/out_of_range/index.md) - exception indicating access out of the defined range + - [**other_error**](https://json.nlohmann.me/api/basic_json/other_error/index.md) - exception indicating other library errors + +### Container types + +| Type | Definition | +| ------------------------ | --------------------------------------------------------------------------------------------------------- | +| `value_type` | `basic_json` | +| `reference` | `value_type&` | +| `const_reference` | `const value_type&` | +| `difference_type` | `std::ptrdiff_t` | +| `size_type` | `std::size_t` | +| `allocator_type` | `AllocatorType` | +| `pointer` | `std::allocator_traits::pointer` | +| `const_pointer` | `std::allocator_traits::const_pointer` | +| `iterator` | [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| `const_iterator` | constant [LegacyBidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator) | +| `reverse_iterator` | reverse iterator, derived from `iterator` | +| `const_reverse_iterator` | reverse iterator, derived from `const_iterator` | +| `iteration_proxy` | helper type for [`items`](https://json.nlohmann.me/api/basic_json/items/index.md) function | + +### JSON value data types + +- [**array_t**](https://json.nlohmann.me/api/basic_json/array_t/index.md) - type for arrays +- [**binary_t**](https://json.nlohmann.me/api/basic_json/binary_t/index.md) - type for binary arrays +- [**boolean_t**](https://json.nlohmann.me/api/basic_json/boolean_t/index.md) - type for booleans +- [**default_object_comparator_t**](https://json.nlohmann.me/api/basic_json/default_object_comparator_t/index.md) - default comparator for objects +- [**number_float_t**](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) - type for numbers (floating-point) +- [**number_integer_t**](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) - type for numbers (integer) +- [**number_unsigned_t**](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) - type for numbers (unsigned) +- [**object_comparator_t**](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md) - comparator for objects +- [**object_t**](https://json.nlohmann.me/api/basic_json/object_t/index.md) - type for objects +- [**string_t**](https://json.nlohmann.me/api/basic_json/string_t/index.md) - type for strings + +### Parser callback + +- [**parse_event_t**](https://json.nlohmann.me/api/basic_json/parse_event_t/index.md) - parser event types +- [**parser_callback_t**](https://json.nlohmann.me/api/basic_json/parser_callback_t/index.md) - per-element parser callback type + +## Member functions + +- [(constructor)](https://json.nlohmann.me/api/basic_json/basic_json/index.md) +- [(destructor)](https://json.nlohmann.me/api/basic_json/~basic_json/index.md) +- [**operator=**](https://json.nlohmann.me/api/basic_json/operator%3D/index.md) - copy assignment +- [**array**](https://json.nlohmann.me/api/basic_json/array/index.md) (*static*) - explicitly create an array +- [**binary**](https://json.nlohmann.me/api/basic_json/binary/index.md) (*static*) - explicitly create a binary array +- [**object**](https://json.nlohmann.me/api/basic_json/object/index.md) (*static*) - explicitly create an object + +### Object inspection + +Functions to inspect the type of a JSON value. + +- [**type**](https://json.nlohmann.me/api/basic_json/type/index.md) - return the type of the JSON value +- [**operator value_t**](https://json.nlohmann.me/api/basic_json/operator_value_t/index.md) - return the type of the JSON value +- [**type_name**](https://json.nlohmann.me/api/basic_json/type_name/index.md) - return the type as string +- [**is_primitive**](https://json.nlohmann.me/api/basic_json/is_primitive/index.md) - return whether the type is primitive +- [**is_structured**](https://json.nlohmann.me/api/basic_json/is_structured/index.md) - return whether the type is structured +- [**is_null**](https://json.nlohmann.me/api/basic_json/is_null/index.md) - return whether the value is null +- [**is_boolean**](https://json.nlohmann.me/api/basic_json/is_boolean/index.md) - return whether the value is a boolean +- [**is_number**](https://json.nlohmann.me/api/basic_json/is_number/index.md) - return whether the value is a number +- [**is_number_integer**](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) - return whether the value is an integer number +- [**is_number_unsigned**](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md) - return whether the value is an unsigned integer number +- [**is_number_float**](https://json.nlohmann.me/api/basic_json/is_number_float/index.md) - return whether the value is a floating-point number +- [**is_object**](https://json.nlohmann.me/api/basic_json/is_object/index.md) - return whether the value is an object +- [**is_array**](https://json.nlohmann.me/api/basic_json/is_array/index.md) - return whether the value is an array +- [**is_string**](https://json.nlohmann.me/api/basic_json/is_string/index.md) - return whether the value is a string +- [**is_binary**](https://json.nlohmann.me/api/basic_json/is_binary/index.md) - return whether the value is a binary array +- [**is_discarded**](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) - return whether the value is discarded + +Optional functions to access the [diagnostic positions](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md). + +- [**start_pos**](https://json.nlohmann.me/api/basic_json/start_pos/index.md) - return the start position of the value +- [**end_pos**](https://json.nlohmann.me/api/basic_json/end_pos/index.md) - return the one past the end position of the value + +### Value access + +Direct access to the stored value of a JSON value. + +- [**get**](https://json.nlohmann.me/api/basic_json/get/index.md) - get a value +- [**get_to**](https://json.nlohmann.me/api/basic_json/get_to/index.md) - get a value and write it to a destination +- [**get_ptr**](https://json.nlohmann.me/api/basic_json/get_ptr/index.md) - get a pointer value +- [**get_ref**](https://json.nlohmann.me/api/basic_json/get_ref/index.md) - get a reference value +- [**operator ValueType**](https://json.nlohmann.me/api/basic_json/operator_ValueType/index.md) - get a value +- [**get_binary**](https://json.nlohmann.me/api/basic_json/get_binary/index.md) - get a binary value + +### Element access + +Access to the JSON value + +- [**at**](https://json.nlohmann.me/api/basic_json/at/index.md) - access specified element with bounds checking +- [**operator[]**](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) - access specified element +- [**value**](https://json.nlohmann.me/api/basic_json/value/index.md) - access specified object element with default value +- [**front**](https://json.nlohmann.me/api/basic_json/front/index.md) - access the first element +- [**back**](https://json.nlohmann.me/api/basic_json/back/index.md) - access the last element + +### Lookup + +- [**find**](https://json.nlohmann.me/api/basic_json/find/index.md) - find an element in a JSON object +- [**count**](https://json.nlohmann.me/api/basic_json/count/index.md) - returns the number of occurrences of a key in a JSON object +- [**contains**](https://json.nlohmann.me/api/basic_json/contains/index.md) - check the existence of an element in a JSON object + +### Iterators + +- [**begin**](https://json.nlohmann.me/api/basic_json/begin/index.md) - returns an iterator to the first element +- [**cbegin**](https://json.nlohmann.me/api/basic_json/cbegin/index.md) - returns a const iterator to the first element +- [**end**](https://json.nlohmann.me/api/basic_json/end/index.md) - returns an iterator to one past the last element +- [**cend**](https://json.nlohmann.me/api/basic_json/cend/index.md) - returns a const iterator to one past the last element +- [**rbegin**](https://json.nlohmann.me/api/basic_json/rbegin/index.md) - returns an iterator to the reverse-beginning +- [**rend**](https://json.nlohmann.me/api/basic_json/rend/index.md) - returns an iterator to the reverse-end +- [**crbegin**](https://json.nlohmann.me/api/basic_json/crbegin/index.md) - returns a const iterator to the reverse-beginning +- [**crend**](https://json.nlohmann.me/api/basic_json/crend/index.md) - returns a const iterator to the reverse-end +- [**items**](https://json.nlohmann.me/api/basic_json/items/index.md) - wrapper to access iterator member functions in range-based for + +### Capacity + +- [**empty**](https://json.nlohmann.me/api/basic_json/empty/index.md) - checks whether the container is empty +- [**size**](https://json.nlohmann.me/api/basic_json/size/index.md) - returns the number of elements +- [**max_size**](https://json.nlohmann.me/api/basic_json/max_size/index.md) - returns the maximum possible number of elements + +### Modifiers + +- [**clear**](https://json.nlohmann.me/api/basic_json/clear/index.md) - clears the contents +- [**push_back**](https://json.nlohmann.me/api/basic_json/push_back/index.md) - add a value to an array/object +- [**operator+=**](https://json.nlohmann.me/api/basic_json/operator%2B%3D/index.md) - add a value to an array/object +- [**emplace_back**](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) - add a value to an array +- [**emplace**](https://json.nlohmann.me/api/basic_json/emplace/index.md) - add a value to an object if a key does not exist +- [**erase**](https://json.nlohmann.me/api/basic_json/erase/index.md) - remove elements +- [**insert**](https://json.nlohmann.me/api/basic_json/insert/index.md) - inserts elements +- [**update**](https://json.nlohmann.me/api/basic_json/update/index.md) - updates a JSON object from another object, overwriting existing keys +- [**swap**](https://json.nlohmann.me/api/basic_json/swap/index.md) - exchanges the values + +### Lexicographical comparison operators + +- [**operator==**](https://json.nlohmann.me/api/basic_json/operator_eq/index.md) - comparison: equal +- [**operator!=**](https://json.nlohmann.me/api/basic_json/operator_ne/index.md) - comparison: not equal +- [**operator\<**](https://json.nlohmann.me/api/basic_json/operator_lt/index.md) - comparison: less than +- [**operator>**](https://json.nlohmann.me/api/basic_json/operator_gt/index.md) - comparison: greater than +- [**operator\<=**](https://json.nlohmann.me/api/basic_json/operator_le/index.md) - comparison: less than or equal +- [**operator>=**](https://json.nlohmann.me/api/basic_json/operator_ge/index.md) - comparison: greater than or equal +- [**operator\<=>**](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) - comparison: 3-way + +### Serialization / Dumping + +- [**dump**](https://json.nlohmann.me/api/basic_json/dump/index.md) - serialization + +### Deserialization / Parsing + +- [**parse**](https://json.nlohmann.me/api/basic_json/parse/index.md) (*static*) - deserialize from a compatible input +- [**accept**](https://json.nlohmann.me/api/basic_json/accept/index.md) (*static*) - check if the input is valid JSON +- [**sax_parse**](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) (*static*) - generate SAX events + +### JSON Pointer functions + +- [**flatten**](https://json.nlohmann.me/api/basic_json/flatten/index.md) - return flattened JSON value +- [**unflatten**](https://json.nlohmann.me/api/basic_json/unflatten/index.md) - unflatten a previously flattened JSON value + +### JSON Patch functions + +- [**patch**](https://json.nlohmann.me/api/basic_json/patch/index.md) - applies a JSON patch +- [**patch_inplace**](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md) - applies a JSON patch in place +- [**diff**](https://json.nlohmann.me/api/basic_json/diff/index.md) (*static*) - creates a diff as a JSON patch + +### JSON Merge Patch functions + +- [**merge_patch**](https://json.nlohmann.me/api/basic_json/merge_patch/index.md) - applies a JSON Merge Patch + +## Static functions + +- [**meta**](https://json.nlohmann.me/api/basic_json/meta/index.md) - returns version information on the library +- [**get_allocator**](https://json.nlohmann.me/api/basic_json/get_allocator/index.md) - returns the allocator associated with the container + +### Binary formats + +- [**from_bjdata**](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md) (*static*) - create a JSON value from an input in BJData format +- [**from_bson**](https://json.nlohmann.me/api/basic_json/from_bson/index.md) (*static*) - create a JSON value from an input in BSON format +- [**from_cbor**](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) (*static*) - create a JSON value from an input in CBOR format +- [**from_msgpack**](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md) (*static*) - create a JSON value from an input in MessagePack format +- [**from_ubjson**](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md) (*static*) - create a JSON value from an input in UBJSON format +- [**to_bjdata**](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) (*static*) - create a BJData serialization of a given JSON value +- [**to_bson**](https://json.nlohmann.me/api/basic_json/to_bson/index.md) (*static*) - create a BSON serialization of a given JSON value +- [**to_cbor**](https://json.nlohmann.me/api/basic_json/to_cbor/index.md) (*static*) - create a CBOR serialization of a given JSON value +- [**to_msgpack**](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) (*static*) - create a MessagePack serialization of a given JSON value +- [**to_ubjson**](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) (*static*) - create a UBJSON serialization of a given JSON value + +## Non-member functions + +- [**operator\<<(std::ostream&)**](https://json.nlohmann.me/api/operator_ltlt/index.md) - serialize to stream +- [**operator>>(std::istream&)**](https://json.nlohmann.me/api/operator_gtgt/index.md) - deserialize from stream +- [**to_string**](https://json.nlohmann.me/api/basic_json/to_string/index.md) - user-defined `to_string` function for JSON values +- [**format_as**](https://json.nlohmann.me/api/basic_json/format_as/index.md) - user-defined `format_as` function for JSON values (fmt support) + +## Literals + +- [**operator""\_json**](https://json.nlohmann.me/api/operator_literal_json/index.md) - user-defined string literal for JSON values + +## Helper classes + +- [**std::formatter\**](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) - make JSON values formattable with `std::format` +- [**std::hash\**](https://json.nlohmann.me/api/basic_json/std_hash/index.md) - return a hash value for a JSON object +- [**std::swap\**](https://json.nlohmann.me/api/basic_json/std_swap/index.md) - exchanges the values of two JSON objects + +## Examples + +Example + +The example shows how the library is used. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j = + { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + { + "answer", { + {"everything", 42} + } + }, + {"list", {1, 0, 2}}, + { + "object", { + {"currency", "USD"}, + {"value", 42.99} + } + } + }; + + // add new values + j["new"]["key"]["value"] = {"another", "list"}; + + // count elements + auto s = j.size(); + j["size"] = s; + + // pretty print with indent of 4 spaces + std::cout << std::setw(4) << j << '\n'; +} +``` + +Output: + +``` +{ + "answer": { + "everything": 42 + }, + "happy": true, + "list": [ + 1, + 0, + 2 + ], + "name": "Niels", + "new": { + "key": { + "value": [ + "another", + "list" + ] + } + }, + "nothing": null, + "object": { + "currency": "USD", + "value": 42.99 + }, + "pi": 3.141, + "size": 8 +} +``` + +## See also + +- [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc8259) + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/input_format_t.md b/api/basic_json/input_format_t.md new file mode 100644 index 000000000..a3baabab8 --- /dev/null +++ b/api/basic_json/input_format_t.md @@ -0,0 +1,52 @@ +# nlohmann::basic_json::input_format_t + +```cpp +enum class input_format_t { + json, + cbor, + msgpack, + ubjson, + bson, + bjdata +}; +``` + +This enumeration is used in the [`sax_parse`](sax_parse.md) function to choose the input format to parse: + +json +: JSON (JavaScript Object Notation) + +cbor +: CBOR (Concise Binary Object Representation) + +msgpack +: MessagePack + +ubjson +: UBJSON (Universal Binary JSON) + +bson +: BSON (Binary JSON) + +bjdata +: BJData (Binary JData) + +## Examples + +??? example + + The example below shows how an `input_format_t` enum value is passed to `sax_parse` to set the input format to CBOR. + + ```cpp + --8<-- "examples/sax_parse__binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse__binary.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/basic_json/input_format_t/index.html b/api/basic_json/input_format_t/index.html index 5d764a68e..12f497f8a 100644 --- a/api/basic_json/input_format_t/index.html +++ b/api/basic_json/input_format_t/index.html @@ -123,4 +123,4 @@

Output:

binary(val=[...])
 
 result: true
-

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/basic_json/input_format_t/index.md b/api/basic_json/input_format_t/index.md new file mode 100644 index 000000000..8d8bd52b7 --- /dev/null +++ b/api/basic_json/input_format_t/index.md @@ -0,0 +1,161 @@ +# nlohmann::basic_json::input_format_t + +``` +enum class input_format_t { + json, + cbor, + msgpack, + ubjson, + bson, + bjdata +}; +``` + +This enumeration is used in the [`sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) function to choose the input format to parse: + +json : JSON (JavaScript Object Notation) + +cbor : CBOR (Concise Binary Object Representation) + +msgpack : MessagePack + +ubjson : UBJSON (Universal Binary JSON) + +bson : BSON (Binary JSON) + +bjdata : BJData (Binary JData) + +## Examples + +Example + +The example below shows how an `input_format_t` enum value is passed to `sax_parse` to set the input format to CBOR. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // CBOR byte string + std::vector vec = {{0x44, 0xcA, 0xfe, 0xba, 0xbe}}; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse CBOR + bool result = json::sax_parse(vec, &sec, json::input_format_t::cbor); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +binary(val=[...]) + +result: true +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/basic_json/insert.md b/api/basic_json/insert.md new file mode 100644 index 000000000..14d5823c1 --- /dev/null +++ b/api/basic_json/insert.md @@ -0,0 +1,197 @@ +# nlohmann::basic_json::insert + +```cpp +// (1) +iterator insert(const_iterator pos, const basic_json& val); +iterator insert(const_iterator pos, basic_json&& val); + +// (2) +iterator insert(const_iterator pos, size_type cnt, const basic_json& val); + +// (3) +iterator insert(const_iterator pos, const_iterator first, const_iterator last); + +// (4) +iterator insert(const_iterator pos, initializer_list_t ilist); + +// (5) +void insert(const_iterator first, const_iterator last); +``` + +1. Inserts element `val` into an array before iterator `pos`. +2. Inserts `cnt` copies of `val` into an array before iterator `pos`. +3. Inserts elements from range `[first, last)` into an array before iterator `pos`. +4. Inserts elements from initializer list `ilist` into an array before iterator `pos`. +5. Inserts elements from range `[first, last)` into an object. + +## Iterator invalidation + +For all cases where an element is added to an **array**, a reallocation can happen, in which case all iterators +(including the [`end()`](end.md) iterator) and all references to the elements are invalidated. Otherwise, only the +[`end()`](end.md) iterator is invalidated. Also, any iterator or reference after the insertion point will point to the +same index, which is now a different value. + +For [`ordered_json`](../ordered_json.md), also adding an element to an **object** can yield a reallocation which again +invalidates all iterators and all references. Also, any iterator or reference after the insertion point will point to +the same index, which is now a different value. + +## Parameters + +`pos` (in) +: iterator before which the content will be inserted; may be the `end()` iterator + +`val` (in) +: value to insert + +`cnt` (in) +: number of copies of `val` to insert + +`first` (in) +: the start of the range of elements to insert + +`last` (in) +: the end of the range of elements to insert + +`ilist` (in) +: initializer list to insert the values from + +## Return value + +1. iterator pointing to the inserted `val`. +2. iterator pointing to the first element inserted, or `pos` if `#!cpp cnt==0` +3. iterator pointing to the first element inserted, or `pos` if `#!cpp first==last` +4. iterator pointing to the first element inserted, or `pos` if `ilist` is empty +5. (none) + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +2. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +3. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last` + do not belong to the same JSON value; example: `"iterators do not fit"` + - Throws [`invalid_iterator.211`](../../home/exceptions.md#jsonexceptioninvalid_iterator211) if `first` or `last` + are iterators into container for which insert is called; example: `"passed iterators may not belong to container"` +4. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if called on an + iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +5. The function can throw the following exceptions: + - Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than + objects; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if `first` or `last` + do not point to an object; example: `"iterators first and last must point to objects"` + - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last` + do not belong to the same JSON value; example: `"iterators do not fit"` + +## Complexity + +1. Constant plus linear in the distance between `pos` and end of the container. +2. Linear in `cnt` plus linear in the distance between `pos` and end of the container. +3. Linear in `#!cpp std::distance(first, last)` plus linear in the distance between `pos` and end of the container. +4. Linear in `ilist.size()` plus linear in the distance between `pos` and end of the container. +5. Logarithmic: `O(N*log(size() + N))`, where `N` is the number of elements to insert. + +## Examples + +??? example "Example (1): insert element into array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert.output" + ``` + +??? example "Example (2): insert copies of element into array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__count.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__count.output" + ``` + +??? example "Example (3): insert a range of elements into an array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__range.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__range.output" + ``` + +??? example "Example (4): insert elements from an initializer list into an array" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__ilist.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__ilist.output" + ``` + +??? example "Example (5): insert a range of elements into an object" + + The example shows how `insert()` is used. + + ```cpp + --8<-- "examples/insert__range_object.cpp" + ``` + + Output: + + ```json + --8<-- "examples/insert__range_object.output" + ``` + +## See also + +- [emplace](emplace.md) add a value to an object +- [emplace_back](emplace_back.md) add a value to an array +- [push_back](push_back.md) add a value to an array/object +- [update](update.md) merges objects + +## Version history + +1. Added in version 1.0.0. +2. Added in version 1.0.0. +3. Added in version 1.0.0. +4. Added in version 1.0.0. +5. Added in version 3.0.0. diff --git a/api/basic_json/insert/index.html b/api/basic_json/insert/index.html index 0452f1099..249c658f2 100644 --- a/api/basic_json/insert/index.html +++ b/api/basic_json/insert/index.html @@ -116,4 +116,4 @@

Output:

{"one":"eins","two":"zwei"}
 {"eleven":"elf","seventeen":"siebzehn"}
 {"eleven":"elf","one":"eins","seventeen":"siebzehn","two":"zwei"}
-

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 1.0.0.
  4. Added in version 1.0.0.
  5. Added in version 3.0.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0.
  3. Added in version 1.0.0.
  4. Added in version 1.0.0.
  5. Added in version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/insert/index.md b/api/basic_json/insert/index.md new file mode 100644 index 000000000..2422179b4 --- /dev/null +++ b/api/basic_json/insert/index.md @@ -0,0 +1,266 @@ +# nlohmann::basic_json::insert + +``` +// (1) +iterator insert(const_iterator pos, const basic_json& val); +iterator insert(const_iterator pos, basic_json&& val); + +// (2) +iterator insert(const_iterator pos, size_type cnt, const basic_json& val); + +// (3) +iterator insert(const_iterator pos, const_iterator first, const_iterator last); + +// (4) +iterator insert(const_iterator pos, initializer_list_t ilist); + +// (5) +void insert(const_iterator first, const_iterator last); +``` + +1. Inserts element `val` into an array before iterator `pos`. +1. Inserts `cnt` copies of `val` into an array before iterator `pos`. +1. Inserts elements from range `[first, last)` into an array before iterator `pos`. +1. Inserts elements from initializer list `ilist` into an array before iterator `pos`. +1. Inserts elements from range `[first, last)` into an object. + +## Iterator invalidation + +For all cases where an element is added to an **array**, a reallocation can happen, in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. Otherwise, only the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator is invalidated. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value. + +For [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), also adding an element to an **object** can yield a reallocation which again invalidates all iterators and all references. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value. + +## Parameters + +`pos` (in) : iterator before which the content will be inserted; may be the `end()` iterator + +`val` (in) : value to insert + +`cnt` (in) : number of copies of `val` to insert + +`first` (in) : the start of the range of elements to insert + +`last` (in) : the end of the range of elements to insert + +`ilist` (in) : initializer list to insert the values from + +## Return value + +1. iterator pointing to the inserted `val`. +1. iterator pointing to the first element inserted, or `pos` if `cnt==0` +1. iterator pointing to the first element inserted, or `pos` if `first==last` +1. iterator pointing to the first element inserted, or `pos` if `ilist` is empty +1. (none) + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.309`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error309) if called on JSON values other than arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) if called on an iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +1. The function can throw the following exceptions: + - Throws [`type_error.309`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error309) if called on JSON values other than arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) if called on an iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +1. The function can throw the following exceptions: + - Throws [`type_error.309`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error309) if called on JSON values other than arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) if called on an iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` + - Throws [`invalid_iterator.210`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator210) if `first` and `last` do not belong to the same JSON value; example: `"iterators do not fit"` + - Throws [`invalid_iterator.211`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator211) if `first` or `last` are iterators into container for which insert is called; example: `"passed iterators may not belong to container"` +1. The function can throw the following exceptions: + - Throws [`type_error.309`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error309) if called on JSON values other than arrays; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) if called on an iterator which does not belong to the current JSON value; example: `"iterator does not fit current value"` +1. The function can throw the following exceptions: + - Throws [`type_error.309`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error309) if called on JSON values other than objects; example: `"cannot use insert() with string"` + - Throws [`invalid_iterator.202`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator202) if `first` or `last` do not point to an object; example: `"iterators first and last must point to objects"` + - Throws [`invalid_iterator.210`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator210) if `first` and `last` do not belong to the same JSON value; example: `"iterators do not fit"` + +## Complexity + +1. Constant plus linear in the distance between `pos` and end of the container. +1. Linear in `cnt` plus linear in the distance between `pos` and end of the container. +1. Linear in `std::distance(first, last)` plus linear in the distance between `pos` and end of the container. +1. Linear in `ilist.size()` plus linear in the distance between `pos` and end of the container. +1. Logarithmic: `O(N*log(size() + N))`, where `N` is the number of elements to insert. + +## Examples + +Example (1): insert element into array + +The example shows how `insert()` is used. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // insert number 10 before number 3 + auto new_pos = v.insert(v.begin() + 2, 10); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} +``` + +Output: + +``` +10 +[1,2,10,3,4] +``` + +Example (2): insert copies of element into array + +The example shows how `insert()` is used. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // insert number 7 copies of number 7 before number 3 + auto new_pos = v.insert(v.begin() + 2, 7, 7); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} +``` + +Output: + +``` +7 +[1,2,7,7,7,7,7,7,7,3,4] +``` + +Example (3): insert a range of elements into an array + +The example shows how `insert()` is used. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // create a JSON array to copy values from + json v2 = {"one", "two", "three", "four"}; + + // insert range from v2 before the end of array v + auto new_pos = v.insert(v.end(), v2.begin(), v2.end()); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} +``` + +Output: + +``` +"one" +[1,2,3,4,"one","two","three","four"] +``` + +Example (4): insert elements from an initializer list into an array + +The example shows how `insert()` is used. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json v = {1, 2, 3, 4}; + + // insert range from v2 before the end of array v + auto new_pos = v.insert(v.end(), {7, 8, 9}); + + // output new array and result of insert call + std::cout << *new_pos << '\n'; + std::cout << v << '\n'; +} +``` + +Output: + +``` +7 +[1,2,3,4,7,8,9] +``` + +Example (5): insert a range of elements into an object + +The example shows how `insert()` is used. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create two JSON objects + json j1 = {{"one", "eins"}, {"two", "zwei"}}; + json j2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}}; + + // output objects + std::cout << j1 << '\n'; + std::cout << j2 << '\n'; + + // insert range from j2 to j1 + j1.insert(j2.begin(), j2.end()); + + // output result of insert call + std::cout << j1 << '\n'; +} +``` + +Output: + +``` +{"one":"eins","two":"zwei"} +{"eleven":"elf","seventeen":"siebzehn"} +{"eleven":"elf","one":"eins","seventeen":"siebzehn","two":"zwei"} +``` + +## See also + +- [emplace](https://json.nlohmann.me/api/basic_json/emplace/index.md) add a value to an object +- [emplace_back](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) add a value to an array +- [push_back](https://json.nlohmann.me/api/basic_json/push_back/index.md) add a value to an array/object +- [update](https://json.nlohmann.me/api/basic_json/update/index.md) merges objects + +## Version history + +1. Added in version 1.0.0. +1. Added in version 1.0.0. +1. Added in version 1.0.0. +1. Added in version 1.0.0. +1. Added in version 3.0.0. diff --git a/api/basic_json/invalid_iterator.md b/api/basic_json/invalid_iterator.md new file mode 100644 index 000000000..6c19a3e7e --- /dev/null +++ b/api/basic_json/invalid_iterator.md @@ -0,0 +1,78 @@ +# nlohmann::basic_json::invalid_iterator + +```cpp +class invalid_iterator : public exception; +``` + +This exception is thrown if iterators passed to a library function do not match the expected semantics. + +Exceptions have ids 2xx (see [list of iterator errors](../../home/exceptions.md#iterator-errors)). + +```mermaid +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_invalid_iterator fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `invalid_iterator` exception can be caught. + + ```cpp + --8<-- "examples/invalid_iterator.cpp" + ``` + + Output: + + ```json + --8<-- "examples/invalid_iterator.output" + ``` + +## See also + +- [`exception`](exception.md) for the base class of all exceptions thrown by the library +- [List of iterator errors](../../home/exceptions.md#iterator-errors) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/invalid_iterator/index.html b/api/basic_json/invalid_iterator/index.html index 5b363d789..55c8c1d97 100644 --- a/api/basic_json/invalid_iterator/index.html +++ b/api/basic_json/invalid_iterator/index.html @@ -50,4 +50,4 @@ }

Output:

message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators
 exception id: 207
-

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file +

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/invalid_iterator/index.md b/api/basic_json/invalid_iterator/index.md new file mode 100644 index 000000000..d390d8b21 --- /dev/null +++ b/api/basic_json/invalid_iterator/index.md @@ -0,0 +1,99 @@ +# nlohmann::basic_json::invalid_iterator + +``` +class invalid_iterator : public exception; +``` + +This exception is thrown if iterators passed to a library function do not match the expected semantics. + +Exceptions have ids 2xx (see [list of iterator errors](https://json.nlohmann.me/home/exceptions/#iterator-errors)). + +``` +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_invalid_iterator fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +Example + +The following code shows how a `invalid_iterator` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling iterator::key() on non-object iterator + json j = "string"; + json::iterator it = j.begin(); + auto k = it.key(); + } + catch (const json::invalid_iterator& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators +exception id: 207 +``` + +## See also + +- [`exception`](https://json.nlohmann.me/api/basic_json/exception/index.md) for the base class of all exceptions thrown by the library +- [List of iterator errors](https://json.nlohmann.me/home/exceptions/#iterator-errors) +- [`parse_error`](https://json.nlohmann.me/api/basic_json/parse_error/index.md) for exceptions indicating a parse error +- [`type_error`](https://json.nlohmann.me/api/basic_json/type_error/index.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](https://json.nlohmann.me/api/basic_json/out_of_range/index.md) for exceptions indicating access out of the defined range +- [`other_error`](https://json.nlohmann.me/api/basic_json/other_error/index.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/is_array.md b/api/basic_json/is_array.md new file mode 100644 index 000000000..64468c357 --- /dev/null +++ b/api/basic_json/is_array.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_array + +```cpp +constexpr bool is_array() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is an array. + +## Return value + +`#!cpp true` if type is an array, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_array()` for all JSON types. + + ```cpp + --8<-- "examples/is_array.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_array.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_array/index.html b/api/basic_json/is_array/index.html index 162ba3761..3be963222 100644 --- a/api/basic_json/is_array/index.html +++ b/api/basic_json/is_array/index.html @@ -38,4 +38,4 @@ true false false -

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_array/index.md b/api/basic_json/is_array/index.md new file mode 100644 index 000000000..f22b99b1f --- /dev/null +++ b/api/basic_json/is_array/index.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::is_array + +``` +constexpr bool is_array() const noexcept; +``` + +This function returns `true` if and only if the JSON value is an array. + +## Return value + +`true` if type is an array, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_array()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_array() + std::cout << std::boolalpha; + std::cout << j_null.is_array() << '\n'; + std::cout << j_boolean.is_array() << '\n'; + std::cout << j_number_integer.is_array() << '\n'; + std::cout << j_number_unsigned_integer.is_array() << '\n'; + std::cout << j_number_float.is_array() << '\n'; + std::cout << j_object.is_array() << '\n'; + std::cout << j_array.is_array() << '\n'; + std::cout << j_string.is_array() << '\n'; + std::cout << j_binary.is_array() << '\n'; +} +``` + +Output: + +``` +false +false +false +false +false +false +true +false +false +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_binary.md b/api/basic_json/is_binary.md new file mode 100644 index 000000000..2a42e5edf --- /dev/null +++ b/api/basic_json/is_binary.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_binary + +```cpp +constexpr bool is_binary() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a binary array. + +## Return value + +`#!cpp true` if type is binary, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_binary()` for all JSON types. + + ```cpp + --8<-- "examples/is_binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_binary.output" + ``` + +## Version history + +- Added in version 3.8.0. diff --git a/api/basic_json/is_binary/index.html b/api/basic_json/is_binary/index.html index 112c27e97..7f53a0ffb 100644 --- a/api/basic_json/is_binary/index.html +++ b/api/basic_json/is_binary/index.html @@ -38,4 +38,4 @@ false false true -

Version history

  • Added in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/is_binary/index.md b/api/basic_json/is_binary/index.md new file mode 100644 index 000000000..4279d1827 --- /dev/null +++ b/api/basic_json/is_binary/index.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::is_binary + +``` +constexpr bool is_binary() const noexcept; +``` + +This function returns `true` if and only if the JSON value is a binary array. + +## Return value + +`true` if type is binary, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_binary()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_binary() + std::cout << std::boolalpha; + std::cout << j_null.is_binary() << '\n'; + std::cout << j_boolean.is_binary() << '\n'; + std::cout << j_number_integer.is_binary() << '\n'; + std::cout << j_number_unsigned_integer.is_binary() << '\n'; + std::cout << j_number_float.is_binary() << '\n'; + std::cout << j_object.is_binary() << '\n'; + std::cout << j_array.is_binary() << '\n'; + std::cout << j_string.is_binary() << '\n'; + std::cout << j_binary.is_binary() << '\n'; +} +``` + +Output: + +``` +false +false +false +false +false +false +false +false +true +``` + +## Version history + +- Added in version 3.8.0. diff --git a/api/basic_json/is_boolean.md b/api/basic_json/is_boolean.md new file mode 100644 index 000000000..dc41d84bd --- /dev/null +++ b/api/basic_json/is_boolean.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_boolean + +```cpp +constexpr bool is_boolean() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is `#!json true` or `#!json false`. + +## Return value + +`#!cpp true` if type is boolean, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_boolean()` for all JSON types. + + ```cpp + --8<-- "examples/is_boolean.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_boolean.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_boolean/index.html b/api/basic_json/is_boolean/index.html index ad9da2aef..e0ec9a0bd 100644 --- a/api/basic_json/is_boolean/index.html +++ b/api/basic_json/is_boolean/index.html @@ -38,4 +38,4 @@ false false false -

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_boolean/index.md b/api/basic_json/is_boolean/index.md new file mode 100644 index 000000000..6069786ff --- /dev/null +++ b/api/basic_json/is_boolean/index.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::is_boolean + +``` +constexpr bool is_boolean() const noexcept; +``` + +This function returns `true` if and only if the JSON value is `true` or `false`. + +## Return value + +`true` if type is boolean, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_boolean()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_boolean() + std::cout << std::boolalpha; + std::cout << j_null.is_boolean() << '\n'; + std::cout << j_boolean.is_boolean() << '\n'; + std::cout << j_number_integer.is_boolean() << '\n'; + std::cout << j_number_unsigned_integer.is_boolean() << '\n'; + std::cout << j_number_float.is_boolean() << '\n'; + std::cout << j_object.is_boolean() << '\n'; + std::cout << j_array.is_boolean() << '\n'; + std::cout << j_string.is_boolean() << '\n'; + std::cout << j_binary.is_boolean() << '\n'; +} +``` + +Output: + +``` +false +true +false +false +false +false +false +false +false +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_discarded.md b/api/basic_json/is_discarded.md new file mode 100644 index 000000000..56fae2a49 --- /dev/null +++ b/api/basic_json/is_discarded.md @@ -0,0 +1,74 @@ +# nlohmann::basic_json::is_discarded + +```cpp +constexpr bool is_discarded() const noexcept; +``` + +This function returns `#!cpp true` for a JSON value if either: + +- the value was discarded during parsing with a callback function (see [`parser_callback_t`](parser_callback_t.md)), or +- the value is the result of parsing invalid JSON with parameter `allow_exceptions` set to `#!cpp false`; see + [`parse`](parse.md) for more information. + +## Return value + +`#!cpp true` if type is discarded, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +!!! note "Comparisons" + + Discarded values are never compared equal with [`operator==`](operator_eq.md). That is, checking whether a JSON + value `j` is discarded will only work via: + + ```cpp + j.is_discarded() + ``` + + because + + ```cpp + j == json::value_t::discarded + ``` + + will always be `#!cpp false`. + +!!! note "Removal during parsing with callback functions" + + When a value is discarded by a callback function (see [`parser_callback_t`](parser_callback_t.md)) during parsing, + then it is removed when it is part of a structured value. For instance, if the second value of an array is discarded, + instead of `#!json [null, discarded, false]`, the array `#!json [null, false]` is returned. If the top-level value + itself is discarded by the callback, the `parse` call returns a `#!json null` value. + +After a successful parse, this function always returns `#!cpp false`: discarded values can only occur during parsing and +are either removed when inside a structured value or replaced by `#!json null` at the top level. The exception is parsing +with `allow_exceptions` set to `#!cpp false`: a parse error then yields a discarded value for which this function returns +`#!cpp true` (see [`parse`](parse.md)). + +## Examples + +??? example + + The following code exemplifies `is_discarded()` for all JSON types. + + ```cpp + --8<-- "examples/is_discarded.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_discarded.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_discarded/index.html b/api/basic_json/is_discarded/index.html index 5de26003e..4966715fb 100644 --- a/api/basic_json/is_discarded/index.html +++ b/api/basic_json/is_discarded/index.html @@ -40,4 +40,4 @@ false false false -

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_discarded/index.md b/api/basic_json/is_discarded/index.md new file mode 100644 index 000000000..45dac6ae1 --- /dev/null +++ b/api/basic_json/is_discarded/index.md @@ -0,0 +1,103 @@ +# nlohmann::basic_json::is_discarded + +``` +constexpr bool is_discarded() const noexcept; +``` + +This function returns `true` for a JSON value if either: + +- the value was discarded during parsing with a callback function (see [`parser_callback_t`](https://json.nlohmann.me/api/basic_json/parser_callback_t/index.md)), or +- the value is the result of parsing invalid JSON with parameter `allow_exceptions` set to `false`; see [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) for more information. + +## Return value + +`true` if type is discarded, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +Comparisons + +Discarded values are never compared equal with [`operator==`](https://json.nlohmann.me/api/basic_json/operator_eq/index.md). That is, checking whether a JSON value `j` is discarded will only work via: + +``` +j.is_discarded() +``` + +because + +``` +j == json::value_t::discarded +``` + +will always be `false`. + +Removal during parsing with callback functions + +When a value is discarded by a callback function (see [`parser_callback_t`](https://json.nlohmann.me/api/basic_json/parser_callback_t/index.md)) during parsing, then it is removed when it is part of a structured value. For instance, if the second value of an array is discarded, instead of `[null, discarded, false]`, the array `[null, false]` is returned. If the top-level value itself is discarded by the callback, the `parse` call returns a `null` value. + +After a successful parse, this function always returns `false`: discarded values can only occur during parsing and are either removed when inside a structured value or replaced by `null` at the top level. The exception is parsing with `allow_exceptions` set to `false`: a parse error then yields a discarded value for which this function returns `true` (see [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md)). + +## Examples + +Example + +The following code exemplifies `is_discarded()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_discarded() + std::cout << std::boolalpha; + std::cout << j_null.is_discarded() << '\n'; + std::cout << j_boolean.is_discarded() << '\n'; + std::cout << j_number_integer.is_discarded() << '\n'; + std::cout << j_number_unsigned_integer.is_discarded() << '\n'; + std::cout << j_number_float.is_discarded() << '\n'; + std::cout << j_object.is_discarded() << '\n'; + std::cout << j_array.is_discarded() << '\n'; + std::cout << j_string.is_discarded() << '\n'; + std::cout << j_binary.is_discarded() << '\n'; +} +``` + +Output: + +``` +false +false +false +false +false +false +false +false +false +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_null.md b/api/basic_json/is_null.md new file mode 100644 index 000000000..d080ad32f --- /dev/null +++ b/api/basic_json/is_null.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_null + +```cpp +constexpr bool is_null() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is `#!json null`. + +## Return value + +`#!cpp true` if type is `#!json null`, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_null()` for all JSON types. + + ```cpp + --8<-- "examples/is_null.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_null.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_null/index.html b/api/basic_json/is_null/index.html index 17db25bff..1adde5a80 100644 --- a/api/basic_json/is_null/index.html +++ b/api/basic_json/is_null/index.html @@ -38,4 +38,4 @@ false false false -

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_null/index.md b/api/basic_json/is_null/index.md new file mode 100644 index 000000000..fef1bdb06 --- /dev/null +++ b/api/basic_json/is_null/index.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::is_null + +``` +constexpr bool is_null() const noexcept; +``` + +This function returns `true` if and only if the JSON value is `null`. + +## Return value + +`true` if type is `null`, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_null()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_null() + std::cout << std::boolalpha; + std::cout << j_null.is_null() << '\n'; + std::cout << j_boolean.is_null() << '\n'; + std::cout << j_number_integer.is_null() << '\n'; + std::cout << j_number_unsigned_integer.is_null() << '\n'; + std::cout << j_number_float.is_null() << '\n'; + std::cout << j_object.is_null() << '\n'; + std::cout << j_array.is_null() << '\n'; + std::cout << j_string.is_null() << '\n'; + std::cout << j_binary.is_null() << '\n'; +} +``` + +Output: + +``` +true +false +false +false +false +false +false +false +false +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_number.md b/api/basic_json/is_number.md new file mode 100644 index 000000000..afb30bb0c --- /dev/null +++ b/api/basic_json/is_number.md @@ -0,0 +1,56 @@ +# nlohmann::basic_json::is_number + +```cpp +constexpr bool is_number() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a number. This includes both integer (signed and +unsigned) and floating-point values. + +## Return value + +`#!cpp true` if type is number (regardless whether integer, unsigned integer, or floating-point), `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +```cpp +constexpr bool is_number() const noexcept +{ + return is_number_integer() || is_number_float(); +} +``` + +## Examples + +??? example + + The following code exemplifies `is_number()` for all JSON types. + + ```cpp + --8<-- "examples/is_number.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number.output" + ``` + +## See also + +- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number +- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number +- [is_number_float()](is_number_float.md) check if the value is a floating-point number + +## Version history + +- Added in version 1.0.0. +- Extended to also return `#!cpp true` for unsigned integers in 2.0.0. diff --git a/api/basic_json/is_number/index.html b/api/basic_json/is_number/index.html index 5a70f975e..00c9aa244 100644 --- a/api/basic_json/is_number/index.html +++ b/api/basic_json/is_number/index.html @@ -42,4 +42,4 @@ false false false -

See also

Version history

  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_number/index.md b/api/basic_json/is_number/index.md new file mode 100644 index 000000000..dd479cbfd --- /dev/null +++ b/api/basic_json/is_number/index.md @@ -0,0 +1,92 @@ +# nlohmann::basic_json::is_number + +``` +constexpr bool is_number() const noexcept; +``` + +This function returns `true` if and only if the JSON value is a number. This includes both integer (signed and unsigned) and floating-point values. + +## Return value + +`true` if type is number (regardless whether integer, unsigned integer, or floating-point), `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +``` +constexpr bool is_number() const noexcept +{ + return is_number_integer() || is_number_float(); +} +``` + +## Examples + +Example + +The following code exemplifies `is_number()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number() + std::cout << std::boolalpha; + std::cout << j_null.is_number() << '\n'; + std::cout << j_boolean.is_number() << '\n'; + std::cout << j_number_integer.is_number() << '\n'; + std::cout << j_number_unsigned_integer.is_number() << '\n'; + std::cout << j_number_float.is_number() << '\n'; + std::cout << j_object.is_number() << '\n'; + std::cout << j_array.is_number() << '\n'; + std::cout << j_string.is_number() << '\n'; + std::cout << j_binary.is_number() << '\n'; +} +``` + +Output: + +``` +false +false +true +true +true +false +false +false +false +``` + +## See also + +- [is_number_integer()](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) check if the value is an integer or unsigned integer number +- [is_number_unsigned()](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md) check if the value is an unsigned integer number +- [is_number_float()](https://json.nlohmann.me/api/basic_json/is_number_float/index.md) check if the value is a floating-point number + +## Version history + +- Added in version 1.0.0. +- Extended to also return `true` for unsigned integers in 2.0.0. diff --git a/api/basic_json/is_number_float.md b/api/basic_json/is_number_float.md new file mode 100644 index 000000000..ad18858e3 --- /dev/null +++ b/api/basic_json/is_number_float.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json::is_number_float + +```cpp +constexpr bool is_number_float() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a floating-point number. This excludes signed and +unsigned integer values. + +## Return value + +`#!cpp true` if type is a floating-point number, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_number_float()` for all JSON types. + + ```cpp + --8<-- "examples/is_number_float.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number_float.output" + ``` + +## See also + +- [is_number()](is_number.md) check if the value is a number +- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number +- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_number_float/index.html b/api/basic_json/is_number_float/index.html index f7e4ce0e9..9f77087f2 100644 --- a/api/basic_json/is_number_float/index.html +++ b/api/basic_json/is_number_float/index.html @@ -38,4 +38,4 @@ false false false -

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_number_float/index.md b/api/basic_json/is_number_float/index.md new file mode 100644 index 000000000..14b4d6d0d --- /dev/null +++ b/api/basic_json/is_number_float/index.md @@ -0,0 +1,82 @@ +# nlohmann::basic_json::is_number_float + +``` +constexpr bool is_number_float() const noexcept; +``` + +This function returns `true` if and only if the JSON value is a floating-point number. This excludes signed and unsigned integer values. + +## Return value + +`true` if type is a floating-point number, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_number_float()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number_float() + std::cout << std::boolalpha; + std::cout << j_null.is_number_float() << '\n'; + std::cout << j_boolean.is_number_float() << '\n'; + std::cout << j_number_integer.is_number_float() << '\n'; + std::cout << j_number_unsigned_integer.is_number_float() << '\n'; + std::cout << j_number_float.is_number_float() << '\n'; + std::cout << j_object.is_number_float() << '\n'; + std::cout << j_array.is_number_float() << '\n'; + std::cout << j_string.is_number_float() << '\n'; + std::cout << j_binary.is_number_float() << '\n'; +} +``` + +Output: + +``` +false +false +false +false +true +false +false +false +false +``` + +## See also + +- [is_number()](https://json.nlohmann.me/api/basic_json/is_number/index.md) check if the value is a number +- [is_number_integer()](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) check if the value is an integer or unsigned integer number +- [is_number_unsigned()](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md) check if the value is an unsigned integer number + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_number_integer.md b/api/basic_json/is_number_integer.md new file mode 100644 index 000000000..b8f971bd6 --- /dev/null +++ b/api/basic_json/is_number_integer.md @@ -0,0 +1,47 @@ +# nlohmann::basic_json::is_number_integer + +```cpp +constexpr bool is_number_integer() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a signed or unsigned integer number. This excludes +floating-point values. + +## Return value + +`#!cpp true` if type is an integer or unsigned integer number, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_number_integer()` for all JSON types. + + ```cpp + --8<-- "examples/is_number_integer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number_integer.output" + ``` + +## See also + +- [is_number()](is_number.md) check if the value is a number +- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number +- [is_number_float()](is_number_float.md) check if the value is a floating-point number + +## Version history + +- Added in version 1.0.0. +- Extended to also return `#!cpp true` for unsigned integers in 2.0.0. diff --git a/api/basic_json/is_number_integer/index.html b/api/basic_json/is_number_integer/index.html index 1492a1dae..2d87d69b2 100644 --- a/api/basic_json/is_number_integer/index.html +++ b/api/basic_json/is_number_integer/index.html @@ -38,4 +38,4 @@ false false false -

See also

Version history

  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_number_integer/index.md b/api/basic_json/is_number_integer/index.md new file mode 100644 index 000000000..5df3ac6e3 --- /dev/null +++ b/api/basic_json/is_number_integer/index.md @@ -0,0 +1,83 @@ +# nlohmann::basic_json::is_number_integer + +``` +constexpr bool is_number_integer() const noexcept; +``` + +This function returns `true` if and only if the JSON value is a signed or unsigned integer number. This excludes floating-point values. + +## Return value + +`true` if type is an integer or unsigned integer number, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_number_integer()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number_integer() + std::cout << std::boolalpha; + std::cout << j_null.is_number_integer() << '\n'; + std::cout << j_boolean.is_number_integer() << '\n'; + std::cout << j_number_integer.is_number_integer() << '\n'; + std::cout << j_number_unsigned_integer.is_number_integer() << '\n'; + std::cout << j_number_float.is_number_integer() << '\n'; + std::cout << j_object.is_number_integer() << '\n'; + std::cout << j_array.is_number_integer() << '\n'; + std::cout << j_string.is_number_integer() << '\n'; + std::cout << j_binary.is_number_integer() << '\n'; +} +``` + +Output: + +``` +false +false +true +true +false +false +false +false +false +``` + +## See also + +- [is_number()](https://json.nlohmann.me/api/basic_json/is_number/index.md) check if the value is a number +- [is_number_unsigned()](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md) check if the value is an unsigned integer number +- [is_number_float()](https://json.nlohmann.me/api/basic_json/is_number_float/index.md) check if the value is a floating-point number + +## Version history + +- Added in version 1.0.0. +- Extended to also return `true` for unsigned integers in 2.0.0. diff --git a/api/basic_json/is_number_unsigned.md b/api/basic_json/is_number_unsigned.md new file mode 100644 index 000000000..50083164e --- /dev/null +++ b/api/basic_json/is_number_unsigned.md @@ -0,0 +1,46 @@ +# nlohmann::basic_json::is_number_unsigned + +```cpp +constexpr bool is_number_unsigned() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is an unsigned integer number. This excludes +floating-point and signed integer values. + +## Return value + +`#!cpp true` if type is an unsigned integer number, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_number_unsigned()` for all JSON types. + + ```cpp + --8<-- "examples/is_number_unsigned.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_number_unsigned.output" + ``` + +## See also + +- [is_number()](is_number.md) check if the value is a number +- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number +- [is_number_float()](is_number_float.md) check if the value is a floating-point number + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/is_number_unsigned/index.html b/api/basic_json/is_number_unsigned/index.html index 44e22d96f..098e308ae 100644 --- a/api/basic_json/is_number_unsigned/index.html +++ b/api/basic_json/is_number_unsigned/index.html @@ -38,4 +38,4 @@ false false false -

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_number_unsigned/index.md b/api/basic_json/is_number_unsigned/index.md new file mode 100644 index 000000000..3adafc462 --- /dev/null +++ b/api/basic_json/is_number_unsigned/index.md @@ -0,0 +1,82 @@ +# nlohmann::basic_json::is_number_unsigned + +``` +constexpr bool is_number_unsigned() const noexcept; +``` + +This function returns `true` if and only if the JSON value is an unsigned integer number. This excludes floating-point and signed integer values. + +## Return value + +`true` if type is an unsigned integer number, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_number_unsigned()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_unsigned_integer = 12345678987654321u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_number_unsigned() + std::cout << std::boolalpha; + std::cout << j_null.is_number_unsigned() << '\n'; + std::cout << j_boolean.is_number_unsigned() << '\n'; + std::cout << j_number_integer.is_number_unsigned() << '\n'; + std::cout << j_number_unsigned_integer.is_number_unsigned() << '\n'; + std::cout << j_number_float.is_number_unsigned() << '\n'; + std::cout << j_object.is_number_unsigned() << '\n'; + std::cout << j_array.is_number_unsigned() << '\n'; + std::cout << j_string.is_number_unsigned() << '\n'; + std::cout << j_binary.is_number_unsigned() << '\n'; +} +``` + +Output: + +``` +false +false +false +true +false +false +false +false +false +``` + +## See also + +- [is_number()](https://json.nlohmann.me/api/basic_json/is_number/index.md) check if the value is a number +- [is_number_integer()](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) check if the value is an integer or unsigned integer number +- [is_number_float()](https://json.nlohmann.me/api/basic_json/is_number_float/index.md) check if the value is a floating-point number + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/is_object.md b/api/basic_json/is_object.md new file mode 100644 index 000000000..04457013b --- /dev/null +++ b/api/basic_json/is_object.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_object + +```cpp +constexpr bool is_object() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is an object. + +## Return value + +`#!cpp true` if type is an object, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_object()` for all JSON types. + + ```cpp + --8<-- "examples/is_object.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_object.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_object/index.html b/api/basic_json/is_object/index.html index 67a8b356d..85ce3d794 100644 --- a/api/basic_json/is_object/index.html +++ b/api/basic_json/is_object/index.html @@ -38,4 +38,4 @@ false false false -

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_object/index.md b/api/basic_json/is_object/index.md new file mode 100644 index 000000000..0ed823563 --- /dev/null +++ b/api/basic_json/is_object/index.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::is_object + +``` +constexpr bool is_object() const noexcept; +``` + +This function returns `true` if and only if the JSON value is an object. + +## Return value + +`true` if type is an object, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_object()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_object() + std::cout << std::boolalpha; + std::cout << j_null.is_object() << '\n'; + std::cout << j_boolean.is_object() << '\n'; + std::cout << j_number_integer.is_object() << '\n'; + std::cout << j_number_unsigned_integer.is_object() << '\n'; + std::cout << j_number_float.is_object() << '\n'; + std::cout << j_object.is_object() << '\n'; + std::cout << j_array.is_object() << '\n'; + std::cout << j_string.is_object() << '\n'; + std::cout << j_binary.is_object() << '\n'; +} +``` + +Output: + +``` +false +false +false +false +false +true +false +false +false +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_primitive.md b/api/basic_json/is_primitive.md new file mode 100644 index 000000000..076c2bfef --- /dev/null +++ b/api/basic_json/is_primitive.md @@ -0,0 +1,69 @@ +# nlohmann::basic_json::is_primitive + +```cpp +constexpr bool is_primitive() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON type is primitive (string, number, boolean, `#!json null`, +binary). + +## Return value + +`#!cpp true` if type is primitive (string, number, boolean, `#!json null`, or binary), `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +```cpp +constexpr bool is_primitive() const noexcept +{ + return is_null() || is_string() || is_boolean() || is_number() || is_binary(); +} +``` + +## Notes + +The term *primitive* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259): + +> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and +> arrays). + +This library extends primitive types to binary types, because binary types are roughly comparable to strings. Hence, +`is_primitive()` returns `#!cpp true` for binary values. + +## Examples + +??? example + + The following code exemplifies `is_primitive()` for all JSON types. + + ```cpp + --8<-- "examples/is_primitive.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_primitive.output" + ``` + +## See also + +- [is_structured()](is_structured.md) returns whether the JSON value is structured +- [is_null()](is_null.md) returns whether the JSON value is `null` +- [is_string()](is_string.md) returns whether the JSON value is a string +- [is_boolean()](is_boolean.md) returns whether the JSON value is a boolean +- [is_number()](is_number.md) returns whether the JSON value is a number +- [is_binary()](is_binary.md) returns whether the JSON value is a binary array + +## Version history + +- Added in version 1.0.0. +- Extended to return `#!cpp true` for binary types in version 3.8.0. diff --git a/api/basic_json/is_primitive/index.html b/api/basic_json/is_primitive/index.html index 1b1ce3009..4a6786af9 100644 --- a/api/basic_json/is_primitive/index.html +++ b/api/basic_json/is_primitive/index.html @@ -42,4 +42,4 @@ false true true -

See also

Version history

  • Added in version 1.0.0.
  • Extended to return true for binary types in version 3.8.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
  • Extended to return true for binary types in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/is_primitive/index.md b/api/basic_json/is_primitive/index.md new file mode 100644 index 000000000..0807cf5a2 --- /dev/null +++ b/api/basic_json/is_primitive/index.md @@ -0,0 +1,103 @@ +# nlohmann::basic_json::is_primitive + +``` +constexpr bool is_primitive() const noexcept; +``` + +This function returns `true` if and only if the JSON type is primitive (string, number, boolean, `null`, binary). + +## Return value + +`true` if type is primitive (string, number, boolean, `null`, or binary), `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +``` +constexpr bool is_primitive() const noexcept +{ + return is_null() || is_string() || is_boolean() || is_number() || is_binary(); +} +``` + +## Notes + +The term *primitive* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259): + +> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays). + +This library extends primitive types to binary types, because binary types are roughly comparable to strings. Hence, `is_primitive()` returns `true` for binary values. + +## Examples + +Example + +The following code exemplifies `is_primitive()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_primitive() + std::cout << std::boolalpha; + std::cout << j_null.is_primitive() << '\n'; + std::cout << j_boolean.is_primitive() << '\n'; + std::cout << j_number_integer.is_primitive() << '\n'; + std::cout << j_number_unsigned_integer.is_primitive() << '\n'; + std::cout << j_number_float.is_primitive() << '\n'; + std::cout << j_object.is_primitive() << '\n'; + std::cout << j_array.is_primitive() << '\n'; + std::cout << j_string.is_primitive() << '\n'; + std::cout << j_binary.is_primitive() << '\n'; +} +``` + +Output: + +``` +true +true +true +true +true +false +false +true +true +``` + +## See also + +- [is_structured()](https://json.nlohmann.me/api/basic_json/is_structured/index.md) returns whether the JSON value is structured +- [is_null()](https://json.nlohmann.me/api/basic_json/is_null/index.md) returns whether the JSON value is `null` +- [is_string()](https://json.nlohmann.me/api/basic_json/is_string/index.md) returns whether the JSON value is a string +- [is_boolean()](https://json.nlohmann.me/api/basic_json/is_boolean/index.md) returns whether the JSON value is a boolean +- [is_number()](https://json.nlohmann.me/api/basic_json/is_number/index.md) returns whether the JSON value is a number +- [is_binary()](https://json.nlohmann.me/api/basic_json/is_binary/index.md) returns whether the JSON value is a binary array + +## Version history + +- Added in version 1.0.0. +- Extended to return `true` for binary types in version 3.8.0. diff --git a/api/basic_json/is_string.md b/api/basic_json/is_string.md new file mode 100644 index 000000000..b82c92465 --- /dev/null +++ b/api/basic_json/is_string.md @@ -0,0 +1,39 @@ +# nlohmann::basic_json::is_string + +```cpp +constexpr bool is_string() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON value is a string. + +## Return value + +`#!cpp true` if type is a string, `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `is_string()` for all JSON types. + + ```cpp + --8<-- "examples/is_string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_string.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_string/index.html b/api/basic_json/is_string/index.html index 259e325db..84275c44e 100644 --- a/api/basic_json/is_string/index.html +++ b/api/basic_json/is_string/index.html @@ -38,4 +38,4 @@ false true false -

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_string/index.md b/api/basic_json/is_string/index.md new file mode 100644 index 000000000..c9a862fb7 --- /dev/null +++ b/api/basic_json/is_string/index.md @@ -0,0 +1,76 @@ +# nlohmann::basic_json::is_string + +``` +constexpr bool is_string() const noexcept; +``` + +This function returns `true` if and only if the JSON value is a string. + +## Return value + +`true` if type is a string, `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `is_string()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_string() + std::cout << std::boolalpha; + std::cout << j_null.is_string() << '\n'; + std::cout << j_boolean.is_string() << '\n'; + std::cout << j_number_integer.is_string() << '\n'; + std::cout << j_number_unsigned_integer.is_string() << '\n'; + std::cout << j_number_float.is_string() << '\n'; + std::cout << j_object.is_string() << '\n'; + std::cout << j_array.is_string() << '\n'; + std::cout << j_string.is_string() << '\n'; + std::cout << j_binary.is_string() << '\n'; +} +``` + +Output: + +``` +false +false +false +false +false +false +false +true +false +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_structured.md b/api/basic_json/is_structured.md new file mode 100644 index 000000000..f2d9e79ff --- /dev/null +++ b/api/basic_json/is_structured.md @@ -0,0 +1,63 @@ +# nlohmann::basic_json::is_structured + +```cpp +constexpr bool is_structured() const noexcept; +``` + +This function returns `#!cpp true` if and only if the JSON type is structured (array or object). + +## Return value + +`#!cpp true` if type is structured (array or object), `#!cpp false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +```cpp +constexpr bool is_structured() const noexcept +{ + return is_array() || is_object(); +} +``` + +## Notes + +The term *structured* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259): + +> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and +> arrays). + +Note that though strings are containers in C++, they are treated as primitive values in JSON. + +## Examples + +??? example + + The following code exemplifies `is_structured()` for all JSON types. + + ```cpp + --8<-- "examples/is_structured.cpp" + ``` + + Output: + + ```json + --8<-- "examples/is_structured.output" + ``` + +## See also + +- [is_primitive()](is_primitive.md) returns whether JSON value is primitive +- [is_array()](is_array.md) returns whether the value is an array +- [is_object()](is_object.md) returns whether the value is an object + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/is_structured/index.html b/api/basic_json/is_structured/index.html index 0c870d356..bd23ce8e9 100644 --- a/api/basic_json/is_structured/index.html +++ b/api/basic_json/is_structured/index.html @@ -42,4 +42,4 @@ true false false -

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/is_structured/index.md b/api/basic_json/is_structured/index.md new file mode 100644 index 000000000..323afb17d --- /dev/null +++ b/api/basic_json/is_structured/index.md @@ -0,0 +1,99 @@ +# nlohmann::basic_json::is_structured + +``` +constexpr bool is_structured() const noexcept; +``` + +This function returns `true` if and only if the JSON type is structured (array or object). + +## Return value + +`true` if type is structured (array or object), `false` otherwise. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +``` +constexpr bool is_structured() const noexcept +{ + return is_array() || is_object(); +} +``` + +## Notes + +The term *structured* stems from [RFC 8259](https://tools.ietf.org/html/rfc8259): + +> JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays). + +Note that though strings are containers in C++, they are treated as primitive values in JSON. + +## Examples + +Example + +The following code exemplifies `is_structured()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_number_unsigned_integer = 12345678987654321u; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + json j_binary = json::binary({1, 2, 3}); + + // call is_structured() + std::cout << std::boolalpha; + std::cout << j_null.is_structured() << '\n'; + std::cout << j_boolean.is_structured() << '\n'; + std::cout << j_number_integer.is_structured() << '\n'; + std::cout << j_number_unsigned_integer.is_structured() << '\n'; + std::cout << j_number_float.is_structured() << '\n'; + std::cout << j_object.is_structured() << '\n'; + std::cout << j_array.is_structured() << '\n'; + std::cout << j_string.is_structured() << '\n'; + std::cout << j_binary.is_structured() << '\n'; +} +``` + +Output: + +``` +false +false +false +false +false +true +true +false +false +``` + +## See also + +- [is_primitive()](https://json.nlohmann.me/api/basic_json/is_primitive/index.md) returns whether JSON value is primitive +- [is_array()](https://json.nlohmann.me/api/basic_json/is_array/index.md) returns whether the value is an array +- [is_object()](https://json.nlohmann.me/api/basic_json/is_object/index.md) returns whether the value is an object + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/items.md b/api/basic_json/items.md new file mode 100644 index 000000000..a45ebdf86 --- /dev/null +++ b/api/basic_json/items.md @@ -0,0 +1,105 @@ +# nlohmann::basic_json::items + +```cpp +iteration_proxy items() noexcept; +iteration_proxy items() const noexcept; +``` + +This function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a +reference to the JSON values is returned, so there is no access to the underlying iterator. + +For loop without `items()` function: + +```cpp +for (auto it = j_object.begin(); it != j_object.end(); ++it) +{ + std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; +} +``` + +Range-based for loop without `items()` function: + +```cpp +for (auto it : j_object) +{ + // "it" is of type json::reference and has no key() member + std::cout << "value: " << it << '\n'; +} +``` + +Range-based for loop with `items()` function: + +```cpp +for (auto& el : j_object.items()) +{ + std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; +} +``` + +The `items()` function also allows using +[structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) (C++17): + +```cpp +for (auto& [key, val] : j_object.items()) +{ + std::cout << "key: " << key << ", value:" << val << '\n'; +} +``` + +## Return value + +iteration proxy object wrapping the current value with an interface to use in range-based for loops + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Constant. + +## Notes + +When iterating over an array, `key()` will return the index of the element as string (see example). For primitive types +(e.g., numbers), `key()` returns an empty string. + +!!! danger "Lifetime issues" + + Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See + [#2040](https://github.com/nlohmann/json/issues/2040) for more information. + +## Examples + +??? example + + The following code shows an example for `items()`. + + ```cpp + --8<-- "examples/items.cpp" + ``` + + Output: + + ```json + --8<-- "examples/items.output" + ``` + +## See also + +- [begin](begin.md) returns an iterator to the first element +- [end](end.md) returns an iterator to one past the last element + +## Version history + +- Added `iterator_wrapper` in version 3.0.0. +- Added `items` and deprecated `iterator_wrapper` in version 3.1.0. +- Added structured binding support in version 3.5.0. + +!!! warning "Deprecation" + + This function replaces the static function `iterator_wrapper` which was introduced in version 1.0.0, but has been + deprecated in version 3.1.0. Function `iterator_wrapper` will be removed in version 4.0.0. Please replace all + occurrences of `#!cpp iterator_wrapper(j)` with `#!cpp j.items()`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/api/basic_json/items/index.html b/api/basic_json/items/index.html index c6988462f..32e99ed76 100644 --- a/api/basic_json/items/index.html +++ b/api/basic_json/items/index.html @@ -47,4 +47,4 @@ key: 2, value: 4 key: 3, value: 8 key: 4, value: 16 -

See also

  • begin returns an iterator to the first element
  • end returns an iterator to one past the last element

Version history

  • Added iterator_wrapper in version 3.0.0.
  • Added items and deprecated iterator_wrapper in version 3.1.0.
  • Added structured binding support in version 3.5.0.

Deprecation

This function replaces the static function iterator_wrapper which was introduced in version 1.0.0, but has been deprecated in version 3.1.0. Function iterator_wrapper will be removed in version 4.0.0. Please replace all occurrences of iterator_wrapper(j) with j.items().

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file +

See also

  • begin returns an iterator to the first element
  • end returns an iterator to one past the last element

Version history

  • Added iterator_wrapper in version 3.0.0.
  • Added items and deprecated iterator_wrapper in version 3.1.0.
  • Added structured binding support in version 3.5.0.

Deprecation

This function replaces the static function iterator_wrapper which was introduced in version 1.0.0, but has been deprecated in version 3.1.0. Function iterator_wrapper will be removed in version 4.0.0. Please replace all occurrences of iterator_wrapper(j) with j.items().

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file diff --git a/api/basic_json/items/index.md b/api/basic_json/items/index.md new file mode 100644 index 000000000..adfb74865 --- /dev/null +++ b/api/basic_json/items/index.md @@ -0,0 +1,126 @@ +# nlohmann::basic_json::items + +``` +iteration_proxy items() noexcept; +iteration_proxy items() const noexcept; +``` + +This function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator. + +For loop without `items()` function: + +``` +for (auto it = j_object.begin(); it != j_object.end(); ++it) +{ + std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; +} +``` + +Range-based for loop without `items()` function: + +``` +for (auto it : j_object) +{ + // "it" is of type json::reference and has no key() member + std::cout << "value: " << it << '\n'; +} +``` + +Range-based for loop with `items()` function: + +``` +for (auto& el : j_object.items()) +{ + std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; +} +``` + +The `items()` function also allows using [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) (C++17): + +``` +for (auto& [key, val] : j_object.items()) +{ + std::cout << "key: " << key << ", value:" << val << '\n'; +} +``` + +## Return value + +iteration proxy object wrapping the current value with an interface to use in range-based for loops + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Constant. + +## Notes + +When iterating over an array, `key()` will return the index of the element as string (see example). For primitive types (e.g., numbers), `key()` returns an empty string. + +Lifetime issues + +Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See [#2040](https://github.com/nlohmann/json/issues/2040) for more information. + +## Examples + +Example + +The following code shows an example for `items()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + + // example for an object + for (auto& x : j_object.items()) + { + std::cout << "key: " << x.key() << ", value: " << x.value() << '\n'; + } + + // example for an array + for (auto& x : j_array.items()) + { + std::cout << "key: " << x.key() << ", value: " << x.value() << '\n'; + } +} +``` + +Output: + +``` +key: one, value: 1 +key: two, value: 2 +key: 0, value: 1 +key: 1, value: 2 +key: 2, value: 4 +key: 3, value: 8 +key: 4, value: 16 +``` + +## See also + +- [begin](https://json.nlohmann.me/api/basic_json/begin/index.md) returns an iterator to the first element +- [end](https://json.nlohmann.me/api/basic_json/end/index.md) returns an iterator to one past the last element + +## Version history + +- Added `iterator_wrapper` in version 3.0.0. +- Added `items` and deprecated `iterator_wrapper` in version 3.1.0. +- Added structured binding support in version 3.5.0. + +Deprecation + +This function replaces the static function `iterator_wrapper` which was introduced in version 1.0.0, but has been deprecated in version 3.1.0. Function `iterator_wrapper` will be removed in version 4.0.0. Please replace all occurrences of `iterator_wrapper(j)` with `j.items()`. + +You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated function. diff --git a/api/basic_json/json_base_class_t.md b/api/basic_json/json_base_class_t.md new file mode 100644 index 000000000..dfe5f1cb7 --- /dev/null +++ b/api/basic_json/json_base_class_t.md @@ -0,0 +1,45 @@ +# nlohmann::basic_json::json_base_class_t + +```cpp +using json_base_class_t = detail::json_base_class; +``` + +The base class used to inject custom functionality into each instance of `basic_json`. +Examples of such functionality might be metadata, additional member functions (e.g., visitors), or other application-specific code. + +## Template parameters + +`CustomBaseClass` +: the base class to be added to `basic_json` + +## Notes + +#### Default type + +The default value for `CustomBaseClass` is `void`. In this case, an +[empty base class](https://en.cppreference.com/w/cpp/language/ebo) is used and no additional functionality is injected. + +#### Limitations + +The type `CustomBaseClass` has to be a default-constructible class. +`basic_json` only supports copy/move construction/assignment if `CustomBaseClass` does so as well. + +## Examples + +??? example + + The following code shows how to inject custom data and methods for each node. + + ```cpp + --8<-- "examples/json_base_class_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_base_class_t.output" + ``` + +## Version history + +- Added in version 3.12.0. diff --git a/api/basic_json/json_base_class_t/index.html b/api/basic_json/json_base_class_t/index.html index 9ee3e6979..6b6a9f732 100644 --- a/api/basic_json/json_base_class_t/index.html +++ b/api/basic_json/json_base_class_t/index.html @@ -91,4 +91,4 @@ /null - metadata = 42 -> null /object - metadata = 21 -> {"uint":1} /object/uint - metadata = 42 -> 1 -

Version history

  • Added in version 3.12.0.
\ No newline at end of file +

Version history

  • Added in version 3.12.0.
\ No newline at end of file diff --git a/api/basic_json/json_base_class_t/index.md b/api/basic_json/json_base_class_t/index.md new file mode 100644 index 000000000..b615a68c4 --- /dev/null +++ b/api/basic_json/json_base_class_t/index.md @@ -0,0 +1,131 @@ +# nlohmann::basic_json::json_base_class_t + +``` +using json_base_class_t = detail::json_base_class; +``` + +The base class used to inject custom functionality into each instance of `basic_json`. Examples of such functionality might be metadata, additional member functions (e.g., visitors), or other application-specific code. + +## Template parameters + +`CustomBaseClass` : the base class to be added to `basic_json` + +## Notes + +#### Default type + +The default value for `CustomBaseClass` is `void`. In this case, an [empty base class](https://en.cppreference.com/w/cpp/language/ebo) is used and no additional functionality is injected. + +#### Limitations + +The type `CustomBaseClass` has to be a default-constructible class. `basic_json` only supports copy/move construction/assignment if `CustomBaseClass` does so as well. + +## Examples + +Example + +The following code shows how to inject custom data and methods for each node. + +``` +#include +#include + +class visitor_adaptor_with_metadata +{ + public: + template + void visit(const Fnc& fnc) const; + + int metadata = 42; + private: + template + void do_visit(const Ptr& ptr, const Fnc& fnc) const; +}; + +using json = nlohmann::basic_json < + std::map, + std::vector, + std::string, + bool, + std::int64_t, + std::uint64_t, + double, + std::allocator, + nlohmann::adl_serializer, + std::vector, + visitor_adaptor_with_metadata + >; + +template +void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const +{ + do_visit(json::json_pointer{}, fnc); +} + +template +void visitor_adaptor_with_metadata::do_visit(const Ptr& ptr, const Fnc& fnc) const +{ + using value_t = nlohmann::detail::value_t; + const json& j = *static_cast(this); + switch (j.type()) + { + case value_t::object: + fnc(ptr, j); + for (const auto& entry : j.items()) + { + entry.value().do_visit(ptr / entry.key(), fnc); + } + break; + case value_t::array: + fnc(ptr, j); + for (std::size_t i = 0; i < j.size(); ++i) + { + j.at(i).do_visit(ptr / std::to_string(i), fnc); + } + break; + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + fnc(ptr, j); + break; + case value_t::discarded: + default: + break; + } +} + +int main() +{ + // create a json object + json j; + j["null"]; + j["object"]["uint"] = 1U; + j["object"].metadata = 21; + + // visit and output + j.visit( + [&](const json::json_pointer & p, + const json & j) + { + std::cout << (p.empty() ? std::string{"/"} : p.to_string()) + << " - metadata = " << j.metadata << " -> " << j.dump() << '\n'; + }); +} +``` + +Output: + +``` +/ - metadata = 42 -> {"null":null,"object":{"uint":1}} +/null - metadata = 42 -> null +/object - metadata = 21 -> {"uint":1} +/object/uint - metadata = 42 -> 1 +``` + +## Version history + +- Added in version 3.12.0. diff --git a/api/basic_json/json_serializer.md b/api/basic_json/json_serializer.md new file mode 100644 index 000000000..24a37735c --- /dev/null +++ b/api/basic_json/json_serializer.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::json_serializer + +```cpp +template +using json_serializer = JSONSerializer; +``` + +## Template parameters + +`T` +: type to convert; will be used in the `to_json`/`from_json` functions + +`SFINAE` +: type to add compile type checks via SFINAE; usually `#!cpp void` + +## Notes + +#### Default type + +The default values for `json_serializer` is [`adl_serializer`](../adl_serializer/index.md). + +## Examples + +??? example + + The example below shows how a conversion of a non-default-constructible type is implemented via a specialization of + the `adl_serializer`. + + ```cpp + --8<-- "examples/from_json__non_default_constructible.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_json__non_default_constructible.output" + ``` + +## Version history + +- Since version 2.0.0. diff --git a/api/basic_json/json_serializer/index.html b/api/basic_json/json_serializer/index.html index 38f137983..1948b5b68 100644 --- a/api/basic_json/json_serializer/index.html +++ b/api/basic_json/json_serializer/index.html @@ -54,4 +54,4 @@ std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl; }

Output:

Ned Flanders (60) lives in 744 Evergreen Terrace
-

Version history

  • Since version 2.0.0.
\ No newline at end of file +

Version history

  • Since version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/json_serializer/index.md b/api/basic_json/json_serializer/index.md new file mode 100644 index 000000000..a753a1d1c --- /dev/null +++ b/api/basic_json/json_serializer/index.md @@ -0,0 +1,90 @@ +# nlohmann::basic_json::json_serializer + +``` +template +using json_serializer = JSONSerializer; +``` + +## Template parameters + +`T` : type to convert; will be used in the `to_json`/`from_json` functions + +`SFINAE` : type to add compile type checks via SFINAE; usually `void` + +## Notes + +#### Default type + +The default values for `json_serializer` is [`adl_serializer`](https://json.nlohmann.me/api/adl_serializer/index.md). + +## Examples + +Example + +The example below shows how a conversion of a non-default-constructible type is implemented via a specialization of the `adl_serializer`. + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +// a simple struct to model a person (not default constructible) +struct person +{ + person(std::string n, std::string a, int aa) + : name(std::move(n)), address(std::move(a)), age(aa) + {} + + std::string name; + std::string address; + int age; +}; +} // namespace ns + +namespace nlohmann +{ +template <> +struct adl_serializer +{ + static ns::person from_json(const json& j) + { + return {j.at("name"), j.at("address"), j.at("age")}; + } + + // Here's the catch! You must provide a to_json method! Otherwise, you + // will not be able to convert person to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, ns::person p) + { + j["name"] = p.name; + j["address"] = p.address; + j["age"] = p.age; + } +}; +} // namespace nlohmann + +int main() +{ + json j; + j["name"] = "Ned Flanders"; + j["address"] = "744 Evergreen Terrace"; + j["age"] = 60; + + auto p = j.get(); + + std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl; +} +``` + +Output: + +``` +Ned Flanders (60) lives in 744 Evergreen Terrace +``` + +## Version history + +- Since version 2.0.0. diff --git a/api/basic_json/max_size.md b/api/basic_json/max_size.md new file mode 100644 index 000000000..4c0c57520 --- /dev/null +++ b/api/basic_json/max_size.md @@ -0,0 +1,60 @@ +# nlohmann::basic_json::max_size + +```cpp +size_type max_size() const noexcept; +``` + +Returns the maximum number of elements a JSON value is able to hold due to system or library implementation limitations, +i.e. `std::distance(begin(), end())` for the JSON value. + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +|------------|-------------------------------------------| +| null | `0` (same as [`size()`](size.md)) | +| boolean | `1` (same as [`size()`](size.md)) | +| string | `1` (same as [`size()`](size.md)) | +| number | `1` (same as [`size()`](size.md)) | +| binary | `1` (same as [`size()`](size.md)) | +| object | result of function `object_t::max_size()` | +| array | result of function `array_t::max_size()` | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the +[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `max_size()` functions have +constant complexity. + +## Notes + +This function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of +string elements the JSON value can store which is `1`. + +## Examples + +??? example + + The following code calls `max_size()` on the different value types. + + ```cpp + --8<-- "examples/max_size.cpp" + ``` + + Output: + + ```json + --8<-- "examples/max_size.output" + ``` + + Note the output is platform-dependent. + +## Version history + +- Added in version 1.0.0. +- Extended to return `1` for binary types in version 3.8.0. diff --git a/api/basic_json/max_size/index.html b/api/basic_json/max_size/index.html index 05a494f86..870a42ec6 100644 --- a/api/basic_json/max_size/index.html +++ b/api/basic_json/max_size/index.html @@ -31,4 +31,4 @@ 115292150460684697 576460752303423487 1 -

Note the output is platform-dependent.

Version history

  • Added in version 1.0.0.
  • Extended to return 1 for binary types in version 3.8.0.
\ No newline at end of file +

Note the output is platform-dependent.

Version history

  • Added in version 1.0.0.
  • Extended to return 1 for binary types in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/max_size/index.md b/api/basic_json/max_size/index.md new file mode 100644 index 000000000..619dcea53 --- /dev/null +++ b/api/basic_json/max_size/index.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::max_size + +``` +size_type max_size() const noexcept; +``` + +Returns the maximum number of elements a JSON value is able to hold due to system or library implementation limitations, i.e. `std::distance(begin(), end())` for the JSON value. + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +| ---------- | ------------------------------------------------------------------------------- | +| null | `0` (same as [`size()`](https://json.nlohmann.me/api/basic_json/size/index.md)) | +| boolean | `1` (same as [`size()`](https://json.nlohmann.me/api/basic_json/size/index.md)) | +| string | `1` (same as [`size()`](https://json.nlohmann.me/api/basic_json/size/index.md)) | +| number | `1` (same as [`size()`](https://json.nlohmann.me/api/basic_json/size/index.md)) | +| binary | `1` (same as [`size()`](https://json.nlohmann.me/api/basic_json/size/index.md)) | +| object | result of function `object_t::max_size()` | +| array | result of function `array_t::max_size()` | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md) and [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md) satisfy the [Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `max_size()` functions have constant complexity. + +## Notes + +This function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of string elements the JSON value can store which is `1`. + +## Examples + +Example + +The following code calls `max_size()` on the different value types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call max_size() + std::cout << j_null.max_size() << '\n'; + std::cout << j_boolean.max_size() << '\n'; + std::cout << j_number_integer.max_size() << '\n'; + std::cout << j_number_float.max_size() << '\n'; + std::cout << j_object.max_size() << '\n'; + std::cout << j_array.max_size() << '\n'; + std::cout << j_string.max_size() << '\n'; +} +``` + +Output: + +``` +0 +1 +1 +1 +115292150460684697 +576460752303423487 +1 +``` + +Note the output is platform-dependent. + +## Version history + +- Added in version 1.0.0. +- Extended to return `1` for binary types in version 3.8.0. diff --git a/api/basic_json/merge_patch.md b/api/basic_json/merge_patch.md new file mode 100644 index 000000000..1718c9227 --- /dev/null +++ b/api/basic_json/merge_patch.md @@ -0,0 +1,63 @@ +# nlohmann::basic_json::merge_patch + +```cpp +void merge_patch(const basic_json& apply_patch); +``` + +The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of +modifications to a target resource's content. This function applies a merge patch to the current JSON value. + +The function implements the following algorithm from Section 2 of +[RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): + +```python +define MergePatch(Target, Patch): + if Patch is an Object: + if Target is not an Object: + Target = {} // Ignore the contents and set it to an empty Object + for each Name/Value pair in Patch: + if Value is null: + if Name exists in Target: + remove the Name/Value pair from Target + else: + Target[Name] = MergePatch(Target[Name], Value) + return Target + else: + return Patch +``` + +Thereby, `Target` is the current object; that is, the patch is applied to the current value. + +## Parameters + +`apply_patch` (in) +: the patch to apply + +## Complexity + +Linear in the lengths of `apply_patch`. + +## Examples + +??? example + + The following code shows how a JSON Merge Patch is applied to a JSON document. + + ```cpp + --8<-- "examples/merge_patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/merge_patch.output" + ``` + +## See also + +- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) +- [patch](patch.md) apply a JSON patch + +## Version history + +- Added in version 3.0.0. diff --git a/api/basic_json/merge_patch/index.html b/api/basic_json/merge_patch/index.html index 87dc7077a..f9781ac34 100644 --- a/api/basic_json/merge_patch/index.html +++ b/api/basic_json/merge_patch/index.html @@ -64,4 +64,4 @@ ], "title": "Hello!" } -

See also

Version history

  • Added in version 3.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/merge_patch/index.md b/api/basic_json/merge_patch/index.md new file mode 100644 index 000000000..e65d19cfe --- /dev/null +++ b/api/basic_json/merge_patch/index.md @@ -0,0 +1,110 @@ +# nlohmann::basic_json::merge_patch + +``` +void merge_patch(const basic_json& apply_patch); +``` + +The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value. + +The function implements the following algorithm from Section 2 of [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): + +``` +define MergePatch(Target, Patch): + if Patch is an Object: + if Target is not an Object: + Target = {} // Ignore the contents and set it to an empty Object + for each Name/Value pair in Patch: + if Value is null: + if Name exists in Target: + remove the Name/Value pair from Target + else: + Target[Name] = MergePatch(Target[Name], Value) + return Target + else: + return Patch +``` + +Thereby, `Target` is the current object; that is, the patch is applied to the current value. + +## Parameters + +`apply_patch` (in) : the patch to apply + +## Complexity + +Linear in the lengths of `apply_patch`. + +## Examples + +Example + +The following code shows how a JSON Merge Patch is applied to a JSON document. + +``` +#include +#include +#include // for std::setw + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json document = R"({ + "title": "Goodbye!", + "author": { + "givenName": "John", + "familyName": "Doe" + }, + "tags": [ + "example", + "sample" + ], + "content": "This will be unchanged" + })"_json; + + // the patch + json patch = R"({ + "title": "Hello!", + "phoneNumber": "+01-123-456-7890", + "author": { + "familyName": null + }, + "tags": [ + "example" + ] + })"_json; + + // apply the patch + document.merge_patch(patch); + + // output original and patched document + std::cout << std::setw(4) << document << std::endl; +} +``` + +Output: + +``` +{ + "author": { + "givenName": "John" + }, + "content": "This will be unchanged", + "phoneNumber": "+01-123-456-7890", + "tags": [ + "example" + ], + "title": "Hello!" +} +``` + +## See also + +- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) +- [patch](https://json.nlohmann.me/api/basic_json/patch/index.md) apply a JSON patch + +## Version history + +- Added in version 3.0.0. diff --git a/api/basic_json/meta.md b/api/basic_json/meta.md new file mode 100644 index 000000000..55476c5f3 --- /dev/null +++ b/api/basic_json/meta.md @@ -0,0 +1,56 @@ +# nlohmann::basic_json::meta + +```cpp +static basic_json meta(); +``` + +This function returns a JSON object with information about the library, including the version number and information on +the platform and compiler. + +## Return value + +JSON object holding version information + +| key | description | +|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). On HP aCC compilers, `compiler` is instead the plain string `hp`. | +| `copyright` | The copyright line for the library as string. | +| `name` | The name of the library as string. | +| `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. | +| `url` | The URL of the project as string. | +| `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). | + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example output of the `meta()` function. + + ```cpp + --8<-- "examples/meta.cpp" + ``` + + Output: + + ```json + --8<-- "examples/meta.output" + ``` + + Note the output is platform-dependent. + +## See also + +- [**NLOHMANN_JSON_VERSION_MAJOR**/**NLOHMANN_JSON_VERSION_MINOR**/**NLOHMANN_JSON_VERSION_PATCH**](../macros/nlohmann_json_version_major.md) + \- library version information + +## Version history + +- Added in version 2.1.0. diff --git a/api/basic_json/meta/index.html b/api/basic_json/meta/index.html index 53efa3479..71efed4fe 100644 --- a/api/basic_json/meta/index.html +++ b/api/basic_json/meta/index.html @@ -27,4 +27,4 @@ "string": "3.12.0" } } -

Note the output is platform-dependent.

See also

Version history

  • Added in version 2.1.0.
\ No newline at end of file +

Note the output is platform-dependent.

See also

Version history

  • Added in version 2.1.0.
\ No newline at end of file diff --git a/api/basic_json/meta/index.md b/api/basic_json/meta/index.md new file mode 100644 index 000000000..2dc510686 --- /dev/null +++ b/api/basic_json/meta/index.md @@ -0,0 +1,81 @@ +# nlohmann::basic_json::meta + +``` +static basic_json meta(); +``` + +This function returns a JSON object with information about the library, including the version number and information on the platform and compiler. + +## Return value + +JSON object holding version information + +| key | description | +| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `compiler` | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version). On HP aCC compilers, `compiler` is instead the plain string `hp`. | +| `copyright` | The copyright line for the library as string. | +| `name` | The name of the library as string. | +| `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`. | +| `url` | The URL of the project as string. | +| `version` | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string). | + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example output of the `meta()` function. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // call meta() + std::cout << std::setw(4) << json::meta() << '\n'; +} +``` + +Output: + +``` +{ + "compiler": { + "c++": "201103", + "family": "gcc", + "version": "12.4.0" + }, + "copyright": "(C) 2013-2026 Niels Lohmann", + "name": "JSON for Modern C++", + "platform": "apple", + "url": "https://github.com/nlohmann/json", + "version": { + "major": 3, + "minor": 12, + "patch": 0, + "string": "3.12.0" + } +} +``` + +Note the output is platform-dependent. + +## See also + +- [**NLOHMANN_JSON_VERSION_MAJOR**/**NLOHMANN_JSON_VERSION_MINOR**/**NLOHMANN_JSON_VERSION_PATCH**](https://json.nlohmann.me/api/macros/nlohmann_json_version_major/index.md) + - library version information + +## Version history + +- Added in version 2.1.0. diff --git a/api/basic_json/number_float_t.md b/api/basic_json/number_float_t.md new file mode 100644 index 000000000..3e8933da6 --- /dev/null +++ b/api/basic_json/number_float_t.md @@ -0,0 +1,70 @@ +# nlohmann::basic_json::number_float_t + +```cpp +using number_float_t = NumberFloatType; +``` + +The type used to store JSON numbers (floating-point). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: +> The representation of numbers is similar to that used in most programming languages. A number is represented in base +> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may +> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that +> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is +known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different +types, [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md) and `number_float_t` are +used. + +To store floating-point numbers in C++, a type is defined by the template parameter `NumberFloatType` which chooses the +type to use. + +## Notes + +#### Default type + +With the default values for `NumberFloatType` (`double`), the default value for `number_float_t` is `#!cpp double`. + +#### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in floating-point literals will + be ignored. Internally, the value will be stored as a decimal number. For instance, the C++ floating-point literal + `01.2` will be serialized to `1.2`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `null`. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: +> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software +> that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good +> interoperability can be achieved by implementations that expect no more precision or range than these provide, in the +> sense that implementations will approximate JSON numbers within the expected precision. + +This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values +smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally +and be serialized to `null`. + +#### Storage + +Floating-point number values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `number_float_t` is by default, a typedef to `#!cpp double`. + + ```cpp + --8<-- "examples/number_float_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/number_float_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/number_float_t/index.html b/api/basic_json/number_float_t/index.html index 22d10024d..39857b1a6 100644 --- a/api/basic_json/number_float_t/index.html +++ b/api/basic_json/number_float_t/index.html @@ -10,4 +10,4 @@ std::cout << std::boolalpha << std::is_same<double, json::number_float_t>::value << std::endl; }

Output:

true
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/number_float_t/index.md b/api/basic_json/number_float_t/index.md new file mode 100644 index 000000000..ce11bf520 --- /dev/null +++ b/api/basic_json/number_float_t/index.md @@ -0,0 +1,67 @@ +# nlohmann::basic_json::number_float_t + +``` +using number_float_t = NumberFloatType; +``` + +The type used to store JSON numbers (floating-point). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: + +> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md), [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) and `number_float_t` are used. + +To store floating-point numbers in C++, a type is defined by the template parameter `NumberFloatType` which chooses the type to use. + +## Notes + +#### Default type + +With the default values for `NumberFloatType` (`double`), the default value for `number_float_t` is `double`. + +#### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in floating-point literals will be ignored. Internally, the value will be stored as a decimal number. For instance, the C++ floating-point literal `01.2` will be serialized to `1.2`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `null`. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. + +This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally and be serialized to `null`. + +#### Storage + +Floating-point number values are stored directly inside a `basic_json` type. + +## Examples + +Example + +The following code shows that `number_float_t` is by default, a typedef to `double`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/number_integer_t.md b/api/basic_json/number_integer_t.md new file mode 100644 index 000000000..79cbdf8ca --- /dev/null +++ b/api/basic_json/number_integer_t.md @@ -0,0 +1,75 @@ +# nlohmann::basic_json::number_integer_t + +```cpp +using number_integer_t = NumberIntegerType; +``` + +The type used to store JSON numbers (integers). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: +> The representation of numbers is similar to that used in most programming languages. A number is represented in base +> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may +> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that +> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is +known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different +types, `number_integer_t`, [`number_unsigned_t`](number_unsigned_t.md) and [`number_float_t`](number_float_t.md) are +used. + +To store integer numbers in C++, a type is defined by the template parameter `NumberIntegerType` which chooses the type +to use. + +## Notes + +#### Default type + +With the default values for `NumberIntegerType` (`std::int64_t`), the default value for `number_integer_t` is +`#!cpp std::int64_t`. + +#### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an + interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ + integer literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and +the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of +range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers +will automatically be stored as [`number_unsigned_t`](number_unsigned_t.md) or [`number_float_t`](number_float_t.md). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: +> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are +> interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is +interoperable. + +#### Storage + +Integer number values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `number_integer_t` is by default, a typedef to `#!cpp std::int64_t`. + + ```cpp + --8<-- "examples/number_integer_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/number_integer_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/number_integer_t/index.html b/api/basic_json/number_integer_t/index.html index c9e9699fa..4b6dc14b7 100644 --- a/api/basic_json/number_integer_t/index.html +++ b/api/basic_json/number_integer_t/index.html @@ -10,4 +10,4 @@ std::cout << std::boolalpha << std::is_same<std::int64_t, json::number_integer_t>::value << std::endl; }

Output:

true
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/number_integer_t/index.md b/api/basic_json/number_integer_t/index.md new file mode 100644 index 000000000..4167f903d --- /dev/null +++ b/api/basic_json/number_integer_t/index.md @@ -0,0 +1,72 @@ +# nlohmann::basic_json::number_integer_t + +``` +using number_integer_t = NumberIntegerType; +``` + +The type used to store JSON numbers (integers). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: + +> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, `number_integer_t`, [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) and [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) are used. + +To store integer numbers in C++, a type is defined by the template parameter `NumberIntegerType` which chooses the type to use. + +## Notes + +#### Default type + +With the default values for `NumberIntegerType` (`std::int64_t`), the default value for `number_integer_t` is `std::int64_t`. + +#### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ integer literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (INT64_MAX) and the minimal integer number that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) or [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: + +> Note that when such software is used, numbers that are integers and are in the range [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is interoperable. + +#### Storage + +Integer number values are stored directly inside a `basic_json` type. + +## Examples + +Example + +The following code shows that `number_integer_t` is by default, a typedef to `std::int64_t`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/number_unsigned_t.md b/api/basic_json/number_unsigned_t.md new file mode 100644 index 000000000..f1010f2a6 --- /dev/null +++ b/api/basic_json/number_unsigned_t.md @@ -0,0 +1,75 @@ +# nlohmann::basic_json::number_unsigned_t + +```cpp +using number_unsigned_t = NumberUnsignedType; +``` + +The type used to store JSON numbers (unsigned). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: +> The representation of numbers is similar to that used in most programming languages. A number is represented in base +> 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may +> be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that +> cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is +known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different +types, [`number_integer_t`](number_integer_t.md), `number_unsigned_t` and [`number_float_t`](number_float_t.md) are +used. + +To store unsigned integer numbers in C++, a type is defined by the template parameter `NumberUnsignedType` which chooses +the type to use. + +## Notes + +#### Default type + +With the default values for `NumberUnsignedType` (`std::uint64_t`), the default value for `number_unsigned_t` is +`#!cpp std::uint64_t`. + +#### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an + interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ + integer literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and +the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow +when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored +as [`number_integer_t`](number_integer_t.md) or [`number_float_t`](number_float_t.md). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: +> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are +> interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange (when considered in conjunction with the `number_integer_t` type) of the exactly supported +range [0, UINT64_MAX], this class's integer type is interoperable. + +#### Storage + +Integer number values are stored directly inside a `basic_json` type. + +## Examples + +??? example + + The following code shows that `number_unsigned_t` is by default, a typedef to `#!cpp std::uint64_t`. + + ```cpp + --8<-- "examples/number_unsigned_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/number_unsigned_t.output" + ``` + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/number_unsigned_t/index.html b/api/basic_json/number_unsigned_t/index.html index 409c883cc..fb2fb0b69 100644 --- a/api/basic_json/number_unsigned_t/index.html +++ b/api/basic_json/number_unsigned_t/index.html @@ -10,4 +10,4 @@ std::cout << std::boolalpha << std::is_same<std::uint64_t, json::number_unsigned_t>::value << std::endl; }

Output:

true
-

Version history

  • Added in version 2.0.0.
\ No newline at end of file +

Version history

  • Added in version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/number_unsigned_t/index.md b/api/basic_json/number_unsigned_t/index.md new file mode 100644 index 000000000..fa61ef880 --- /dev/null +++ b/api/basic_json/number_unsigned_t/index.md @@ -0,0 +1,72 @@ +# nlohmann::basic_json::number_unsigned_t + +``` +using number_unsigned_t = NumberUnsignedType; +``` + +The type used to store JSON numbers (unsigned). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: + +> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md), `number_unsigned_t` and [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) are used. + +To store unsigned integer numbers in C++, a type is defined by the template parameter `NumberUnsignedType` which chooses the type to use. + +## Notes + +#### Default type + +With the default values for `NumberUnsignedType` (`std::uint64_t`), the default value for `number_unsigned_t` is `std::uint64_t`. + +#### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ integer literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `18446744073709551615` (UINT64_MAX) and the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) or [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md). + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: + +> Note that when such software is used, numbers that are integers and are in the range [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange (when considered in conjunction with the `number_integer_t` type) of the exactly supported range [0, UINT64_MAX], this class's integer type is interoperable. + +#### Storage + +Integer number values are stored directly inside a `basic_json` type. + +## Examples + +Example + +The following code shows that `number_unsigned_t` is by default, a typedef to `std::uint64_t`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/object.md b/api/basic_json/object.md new file mode 100644 index 000000000..53d969e56 --- /dev/null +++ b/api/basic_json/object.md @@ -0,0 +1,64 @@ +# nlohmann::basic_json::object + +```cpp +static basic_json object(initializer_list_t init = {}); +``` + +Creates a JSON object value from a given initializer list. The initializer lists elements must be pairs, and their first +elements must be strings. If the initializer list is empty, the empty object `#!json {}` is created. + +## Parameters + +`init` (in) +: initializer list with JSON values to create an object from (optional) + +## Return value + +JSON object value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +Throws [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `init` is not a list of pairs whose +first elements are strings. In this case, no object can be created. When such a value is passed to +`basic_json(initializer_list_t, bool, value_t)`, an array would have been created from the passed initializer list +`init`. See the example below. + +## Complexity + +Linear in the size of `init`. + +## Notes + +This function is only added for symmetry reasons. In contrast to the related function `array(initializer_list_t)`, there +are no cases that can only be expressed by this function. That is, any initializer list `init` can also be passed to +the initializer list constructor `basic_json(initializer_list_t, bool, value_t)`. + +## Examples + +??? example + + The following code shows an example for the `object` function. + + ```cpp + --8<-- "examples/object.cpp" + ``` + + Output: + + ```json + --8<-- "examples/object.output" + ``` + +## See also + +- [`basic_json(initializer_list_t)`](basic_json.md) - create a JSON value from an initializer list +- [`array`](array.md) - create a JSON array value from an initializer list +- [Creating JSON values](../../features/creating_values.md) - the article on creating JSON values + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/object/index.html b/api/basic_json/object/index.html index 6a7f046ed..550085283 100644 --- a/api/basic_json/object/index.html +++ b/api/basic_json/object/index.html @@ -31,4 +31,4 @@ {} {"one":1,"two":2} [json.exception.type_error.301] cannot create object from initializer list -

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/object/index.md b/api/basic_json/object/index.md new file mode 100644 index 000000000..8c846ebc4 --- /dev/null +++ b/api/basic_json/object/index.md @@ -0,0 +1,87 @@ +# nlohmann::basic_json::object + +``` +static basic_json object(initializer_list_t init = {}); +``` + +Creates a JSON object value from a given initializer list. The initializer lists elements must be pairs, and their first elements must be strings. If the initializer list is empty, the empty object `{}` is created. + +## Parameters + +`init` (in) : initializer list with JSON values to create an object from (optional) + +## Return value + +JSON object value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +Throws [`type_error.301`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error301) if `init` is not a list of pairs whose first elements are strings. In this case, no object can be created. When such a value is passed to `basic_json(initializer_list_t, bool, value_t)`, an array would have been created from the passed initializer list `init`. See the example below. + +## Complexity + +Linear in the size of `init`. + +## Notes + +This function is only added for symmetry reasons. In contrast to the related function `array(initializer_list_t)`, there are no cases that can only be expressed by this function. That is, any initializer list `init` can also be passed to the initializer list constructor `basic_json(initializer_list_t, bool, value_t)`. + +## Examples + +Example + +The following code shows an example for the `object` function. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON objects + json j_no_init_list = json::object(); + json j_empty_init_list = json::object({}); + json j_list_of_pairs = json::object({ {"one", 1}, {"two", 2} }); + + // serialize the JSON objects + std::cout << j_no_init_list << '\n'; + std::cout << j_empty_init_list << '\n'; + std::cout << j_list_of_pairs << '\n'; + + // example for an exception + try + { + // can only create an object from a list of pairs + json j_invalid_object = json::object({{ "one", 1, 2 }}); + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +{} +{} +{"one":1,"two":2} +[json.exception.type_error.301] cannot create object from initializer list +``` + +## See also + +- [`basic_json(initializer_list_t)`](https://json.nlohmann.me/api/basic_json/basic_json/index.md) - create a JSON value from an initializer list +- [`array`](https://json.nlohmann.me/api/basic_json/array/index.md) - create a JSON array value from an initializer list +- [Creating JSON values](https://json.nlohmann.me/features/creating_values/index.md) - the article on creating JSON values + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/object_comparator_t.md b/api/basic_json/object_comparator_t.md new file mode 100644 index 000000000..d41b98229 --- /dev/null +++ b/api/basic_json/object_comparator_t.md @@ -0,0 +1,32 @@ +# nlohmann::basic_json::object_comparator_t + +```cpp +using object_comparator_t = typename object_t::key_compare; +// or +using object_comparator_t = default_object_comparator_t; +``` + +The comparator used by [`object_t`](object_t.md). Defined as `#!cpp typename object_t::key_compare` if available, +and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise. + +## Examples + +??? example + + The example below demonstrates the used object comparator. + + ```cpp + --8<-- "examples/object_comparator_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/object_comparator_t.output" + ``` + +## Version history + +- Added in version 3.0.0. +- Changed to be conditionally defined as `#!cpp typename object_t::key_compare` or `default_object_comparator_t` in + version 3.11.0. diff --git a/api/basic_json/object_comparator_t/index.html b/api/basic_json/object_comparator_t/index.html index fe11b1b7e..e0e128cf0 100644 --- a/api/basic_json/object_comparator_t/index.html +++ b/api/basic_json/object_comparator_t/index.html @@ -14,4 +14,4 @@ }

Output:

json::object_comparator_t("one", "two") = true
 json::object_comparator_t("three", "four") = false
-

Version history

  • Added in version 3.0.0.
  • Changed to be conditionally defined as typename object_t::key_compare or default_object_comparator_t in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 3.0.0.
  • Changed to be conditionally defined as typename object_t::key_compare or default_object_comparator_t in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/object_comparator_t/index.md b/api/basic_json/object_comparator_t/index.md new file mode 100644 index 000000000..0d8c85a92 --- /dev/null +++ b/api/basic_json/object_comparator_t/index.md @@ -0,0 +1,41 @@ +# nlohmann::basic_json::object_comparator_t + +``` +using object_comparator_t = typename object_t::key_compare; +// or +using object_comparator_t = default_object_comparator_t; +``` + +The comparator used by [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md). Defined as `typename object_t::key_compare` if available, and [`default_object_comparator_t`](https://json.nlohmann.me/api/basic_json/default_object_comparator_t/index.md) otherwise. + +## Examples + +Example + +The example below demonstrates the used object comparator. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha + << "json::object_comparator_t(\"one\", \"two\") = " << json::object_comparator_t{}("one", "two") << "\n" + << "json::object_comparator_t(\"three\", \"four\") = " << json::object_comparator_t{}("three", "four") << std::endl; +} +``` + +Output: + +``` +json::object_comparator_t("one", "two") = true +json::object_comparator_t("three", "four") = false +``` + +## Version history + +- Added in version 3.0.0. +- Changed to be conditionally defined as `typename object_t::key_compare` or `default_object_comparator_t` in version 3.11.0. diff --git a/api/basic_json/object_t.md b/api/basic_json/object_t.md new file mode 100644 index 000000000..7dda42d2b --- /dev/null +++ b/api/basic_json/object_t.md @@ -0,0 +1,114 @@ +# nlohmann::basic_json::object_t + +```cpp +using object_t = ObjectType>>; +``` + +The type used to store JSON objects. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: +> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a +> string, number, boolean, null, object, or array. + +To store objects in C++, a type is defined by the template parameters described below. + +## Template parameters + +`ObjectType` +: the container to store objects (e.g., `std::map` or `std::unordered_map`) + +`StringType` +: the type of the keys or names (e.g., `std::string`). The comparison function `std::less` is used to + order elements inside the container. + +`AllocatorType` +: the allocator to use for objects (e.g., `std::allocator`) + +## Notes + +#### Default type + +With the default values for `ObjectType` (`std::map`), `StringType` (`std::string`), and `AllocatorType` +(`std::allocator`), the default value for `object_t` is: + +```cpp +// until C++14 +std::map< + std::string, // key_type + basic_json, // value_type + std::less, // key_compare + std::allocator> // allocator_type +> + +// since C++14 +std::map< + std::string, // key_type + basic_json, // value_type + std::less<>, // key_compare + std::allocator> // allocator_type +> +``` + +See [`default_object_comparator_t`](default_object_comparator_t.md) for more information. + +#### Behavior + +The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following +behavior: + +- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that + object will agree on the name-value mappings. +- When the names within an object are not unique, it is unspecified which one of the values for a given key will be + chosen. For instance, `#!json {"key": 2, "key": 1}` could be equal to either `#!json {"key": 1}` or + `#!json {"key": 2}`. +- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see + [`dump`](dump.md)) in this order. For instance, `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be stored + and serialized as `#!json {"a": 2, "b": 1}`. +- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense + that they will not be affected by these differences. For instance, `#!json {"b": 1, "a": 2}` and + `#!json {"a": 2, "b": 1}` will be treated as equal. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: +> An implementation may set limits on the maximum depth of nesting. + +In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be +introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the +[`max_size`](max_size.md) function of a JSON object. + +#### Storage + +Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type +`object_t*` must be dereferenced. + +#### Object key order + +The order name/value pairs are added to the object are *not* preserved by the library. Therefore, iterating an object +may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in +alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to +[RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON +objects. + +## Examples + +??? example + + The following code shows that `object_t` is by default, a typedef to `#!cpp std::map`. + + ```cpp + --8<-- "examples/object_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/object_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/object_t/index.html b/api/basic_json/object_t/index.html index 3a14cd9fd..248277cf0 100644 --- a/api/basic_json/object_t/index.html +++ b/api/basic_json/object_t/index.html @@ -28,4 +28,4 @@ std::cout << std::boolalpha << std::is_same<std::map<json::string_t, json>, json::object_t>::value << std::endl; }

Output:

true
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/object_t/index.md b/api/basic_json/object_t/index.md new file mode 100644 index 000000000..fa869c3bf --- /dev/null +++ b/api/basic_json/object_t/index.md @@ -0,0 +1,104 @@ +# nlohmann::basic_json::object_t + +``` +using object_t = ObjectType>>; +``` + +The type used to store JSON objects. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: + +> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array. + +To store objects in C++, a type is defined by the template parameters described below. + +## Template parameters + +`ObjectType` : the container to store objects (e.g., `std::map` or `std::unordered_map`) + +`StringType` : the type of the keys or names (e.g., `std::string`). The comparison function `std::less` is used to order elements inside the container. + +`AllocatorType` : the allocator to use for objects (e.g., `std::allocator`) + +## Notes + +#### Default type + +With the default values for `ObjectType` (`std::map`), `StringType` (`std::string`), and `AllocatorType` (`std::allocator`), the default value for `object_t` is: + +``` +// until C++14 +std::map< + std::string, // key_type + basic_json, // value_type + std::less, // key_compare + std::allocator> // allocator_type +> + +// since C++14 +std::map< + std::string, // key_type + basic_json, // value_type + std::less<>, // key_compare + std::allocator> // allocator_type +> +``` + +See [`default_object_comparator_t`](https://json.nlohmann.me/api/basic_json/default_object_comparator_t/index.md) for more information. + +#### Behavior + +The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following behavior: + +- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings. +- When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or `{"key": 2}`. +- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md)) in this order. For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored and serialized as `{"a": 2, "b": 1}`. +- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be treated as equal. + +#### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the [`max_size`](https://json.nlohmann.me/api/basic_json/max_size/index.md) function of a JSON object. + +#### Storage + +Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type `object_t*` must be dereferenced. + +#### Object key order + +The order name/value pairs are added to the object are *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON objects. + +## Examples + +Example + +The following code shows that `object_t` is by default, a typedef to `std::map`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same, json::object_t>::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/operator%2B%3D.md b/api/basic_json/operator%2B%3D.md new file mode 100644 index 000000000..f296d5c4a --- /dev/null +++ b/api/basic_json/operator%2B%3D.md @@ -0,0 +1,127 @@ +# nlohmann::basic_json::operator+= + +```cpp +// (1) +reference operator+=(basic_json&& val); +reference operator+=(const basic_json& val); + +// (2) +reference operator+=(const typename object_t::value_type& val); + +// (3) +reference operator+=(initializer_list_t init); +``` + +1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an + empty array is created before appending `val`. + +2. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object + is created before inserting `val`. + +3. This function allows using `operator+=` with an initializer list. In case + + 1. the current value is an object, + 2. the initializer list `init` contains only two elements, and + 3. the first element of `init` is a string, + + `init` is converted into an object element and added using `operator+=(const typename object_t::value_type&)`. + Otherwise, `init` is converted to a JSON value and added using `operator+=(basic_json&&)`. + +## Iterator invalidation + +For all cases where an element is added to an **array**, a reallocation can happen, in which case all iterators (including +the [`end()`](end.md) iterator) and all references to the elements are invalidated. Otherwise, only the +[`end()`](end.md) iterator is invalidated. + +For [`ordered_json`](../ordered_json.md), also adding an element to an **object** can yield a reallocation which again +invalidates all iterators and all references. + +## Parameters + +`val` (in) +: the value to add to the JSON array/object + +`init` (in) +: an initializer list + +## Return value + +`#!cpp *this` + +## Exceptions + +1. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON array or null; example: `"cannot use push_back() with number"` +2. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON object or null; example: `"cannot use push_back() with number"` +3. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON array or null; example: `"cannot use push_back() with number"` + +## Complexity + +1. Amortized constant. +2. Logarithmic in the size of the container, O(log(`size()`)). +3. Linear in the size of the initializer list `init`. + +## Notes + +(3) This function is required to resolve an ambiguous overload error, because pairs like `{"key", "value"}` can be both +interpreted as `object_t::value_type` or `std::initializer_list`, see +[#235](https://github.com/nlohmann/json/issues/235) for more information. + +## Examples + +??? example "Example: (1) add element to array" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value + was silently converted to a JSON array. + + ```cpp + --8<-- "examples/push_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back.output" + ``` + +??? example "Example: (2) add element to object" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value + was silently converted to a JSON object. + + ```cpp + --8<-- "examples/push_back__object_t__value.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__object_t__value.output" + ``` + +??? example "Example: (3) add to object from initializer list" + + The example shows how initializer lists are treated as objects when possible. + + ```cpp + --8<-- "examples/push_back__initializer_list.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__initializer_list.output" + ``` + +## See also + +- [emplace_back](emplace_back.md) add a value to an array +- [push_back](push_back.md) add a value to an array/object + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +3. Since version 2.0.0. diff --git a/api/basic_json/operator%3D.md b/api/basic_json/operator%3D.md new file mode 100644 index 000000000..4639783de --- /dev/null +++ b/api/basic_json/operator%3D.md @@ -0,0 +1,53 @@ +# nlohmann::basic_json::operator= + +```cpp +basic_json& operator=(basic_json other) noexcept ( + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_assignable::value +); +``` + +Copy assignment operator. Copies a JSON value via the "copy and swap" strategy: It is expressed in terms of the copy +constructor, destructor, and the `swap()` member function. + +## Parameters + +`other` (in) +: value to copy from + +## Exception safety + +Strong guarantee: if an exception is thrown while copying `other`, there are no changes to `#!cpp *this`. + +## Complexity + +Linear. + +## Examples + +??? example + + The code below shows and example for the copy assignment. It creates a copy of value `a` which is then swapped with + `b`. Finally, the copy of `a` (which is the null value after the swap) is destroyed. + + ```cpp + --8<-- "examples/basic_json__copyassignment.cpp" + ``` + + Output: + + ```json + --8<-- "examples/basic_json__copyassignment.output" + ``` + +## See also + +- [basic_json](basic_json.md) create a JSON value +- [swap](swap.md) exchanges the contents of two JSON values + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/operator%5B%5D.md b/api/basic_json/operator%5B%5D.md new file mode 100644 index 000000000..5109cdcac --- /dev/null +++ b/api/basic_json/operator%5B%5D.md @@ -0,0 +1,255 @@ +# nlohmann::basic_json::operator[] + +```cpp +// (1) +reference operator[](size_type idx); +const_reference operator[](size_type idx) const; + +// (2) +reference operator[](typename object_t::key_type key); +const_reference operator[](const typename object_t::key_type& key) const; + +// (3) +template +reference operator[](KeyType&& key); +template +const_reference operator[](KeyType&& key) const; + +// (4) +reference operator[](const json_pointer& ptr); +const_reference operator[](const json_pointer& ptr) const; +``` + +1. Returns a reference to the array element at specified location `idx`. +2. Returns a reference to the object element with specified key `key`. The non-const qualified overload takes the key by + value. +3. See 2. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. +4. Returns a reference to the element with specified JSON pointer `ptr`. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). + +## Iterator invalidation + +For the non-const versions 1. and 4., when passing an **array** index that does not exist, it is created and filled with +a `#!json null` value before a reference to it is returned. For this, a reallocation can happen, in which case all +iterators (including the [`end()`](end.md) iterator) and all references to the elements are invalidated. + +For [`ordered_json`](../ordered_json.md), also passing an **object key** to the non-const versions 2., 3., and 4., a +reallocation can happen which again invalidates all iterators and all references. + +## Parameters + +`idx` (in) +: index of the element to access + +`key` (in) +: object key of the element to access + +`ptr` (in) +: JSON pointer to the desired element + +## Return value + +1. (const) reference to the element at index `idx` +2. (const) reference to the element at key `key` +3. (const) reference to the element at key `key` +4. (const) reference to the element pointed to by `ptr` + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an array + or null; in that case, using the `[]` operator with an index makes no sense. +2. The function can throw the following exceptions: + - Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an object + or null; in that case, using the `[]` operator with a key makes no sense. +3. See 2. +4. The function can throw the following exceptions: + - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in the passed + JSON pointer `ptr` begins with '0'. + - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in the passed + JSON pointer `ptr` is not a number. + - Throws [`out_of_range.402`](../../home/exceptions.md#jsonexceptionout_of_range402) if the array index '-' is used + in the passed JSON pointer `ptr` for the const version. + - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if the JSON pointer `ptr` can + not be resolved. + - Throws [`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) if an array index in the passed + JSON pointer `ptr` exceeds the range of `size_type` (e.g., on 32-bit platforms). + +## Complexity + +1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`. +2. Logarithmic in the size of the container. +3. Logarithmic in the size of the container. +4. Logarithmic in the size of the container. + +## Notes + +!!! danger "Undefined behavior and runtime assertions" + + The following cases apply to the **const** overloads; the non-const overloads instead insert the missing element + (see the notes below). + + 1. If the element at index `idx` does not exist, the behavior is undefined. + 2. If the element with key `key` does not exist, the behavior is undefined and is **guarded by a + [runtime assertion](../../features/assertions.md)**! + +1. The non-const version may add values: If `idx` is beyond the range of the array (i.e., `idx >= size()`), then the + array is silently filled up with `#!json null` values to make `idx` a valid reference to the last stored element. In + case the value was `#!json null` before, it is converted to an array. + +2. If `key` is not found in the object, then it is silently added to the object and filled with a `#!json null` value to + make `key` a valid reference. In case the value was `#!json null` before, it is converted to an object. + +3. See 2. + +4. `null` values are created in arrays and objects if necessary. + + In particular: + + - If the JSON pointer points to an object key that does not exist, it is created and filled with a `#!json null` + value before a reference to it is returned. + - If the JSON pointer points to an array index that does not exist, it is created and filled with a `#!json null` + value before a reference to it is returned. All indices between the current maximum and the given index are also + filled with `#!json null`. + - The special value `-` is treated as a synonym for the index past the end. + +## Examples + +??? example "Example: (1) access specified array element" + + The example below shows how array elements can be read and written using `[]` operator. Note the addition of + `#!json null` values. + + ```cpp + --8<-- "examples/operator_array__size_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__size_type.output" + ``` + +??? example "Example: (1) access specified array element (const)" + + The example below shows how array elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__size_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__size_type_const.output" + ``` + +??? example "Example: (2) access specified object element" + + The example below shows how object elements can be read and written using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__object_t_key_type.output" + ``` + +??? example "Example: (2) access specified object element (const)" + + The example below shows how object elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__object_t_key_type_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__object_t_key_type_const.output" + ``` + +??? example "Example: (3) access specified object element using string_view" + + The example below shows how object elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__keytype.c++17.output" + ``` + +??? example "Example: (3) access specified object element using string_view (const)" + + The example below shows how object elements can be read using the `[]` operator. + + ```cpp + --8<-- "examples/operator_array__keytype_const.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__keytype_const.c++17.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer" + + The example below shows how values can be read and written using JSON Pointers. + + ```cpp + --8<-- "examples/operator_array__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__json_pointer.output" + ``` + +??? example "Example: (4) access specified element via JSON Pointer (const)" + + The example below shows how values can be read using JSON Pointers. + + ```cpp + --8<-- "examples/operator_array__json_pointer_const.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_array__json_pointer_const.output" + ``` + +## See also + +- documentation on [unchecked access](../../features/element_access/unchecked_access.md) +- documentation on [runtime assertions](../../features/assertions.md) +- see [`at`](at.md) for access by reference with range checking +- see [`value`](value.md) for access with default value + +## Version history + +1. Added in version 1.0.0. +2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3) + in version 3.11.0. +3. Added in version 3.11.0. +4. Added in version 2.0.0. diff --git a/api/basic_json/operator+=/index.html b/api/basic_json/operator+=/index.html index 185ab52cf..36c9e8933 100644 --- a/api/basic_json/operator+=/index.html +++ b/api/basic_json/operator+=/index.html @@ -96,4 +96,4 @@ null {"four":4,"one":1,"three":3,"two":2} [["five",5]] -

See also

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.0.0.
\ No newline at end of file +

See also

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/operator+=/index.md b/api/basic_json/operator+=/index.md new file mode 100644 index 000000000..66b14290d --- /dev/null +++ b/api/basic_json/operator+=/index.md @@ -0,0 +1,195 @@ +# nlohmann::basic_json::operator+= + +``` +// (1) +reference operator+=(basic_json&& val); +reference operator+=(const basic_json& val); + +// (2) +reference operator+=(const typename object_t::value_type& val); + +// (3) +reference operator+=(initializer_list_t init); +``` + +1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an empty array is created before appending `val`. + +1. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object is created before inserting `val`. + +1. This function allows using `operator+=` with an initializer list. In case + + 1. the current value is an object, + 1. the initializer list `init` contains only two elements, and + 1. the first element of `init` is a string, + + `init` is converted into an object element and added using `operator+=(const typename object_t::value_type&)`. Otherwise, `init` is converted to a JSON value and added using `operator+=(basic_json&&)`. + +## Iterator invalidation + +For all cases where an element is added to an **array**, a reallocation can happen, in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. Otherwise, only the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator is invalidated. + +For [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), also adding an element to an **object** can yield a reallocation which again invalidates all iterators and all references. + +## Parameters + +`val` (in) : the value to add to the JSON array/object + +`init` (in) : an initializer list + +## Return value + +`*this` + +## Exceptions + +1. Throws [`type_error.308`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error308) when called on a type other than JSON array or null; example: `"cannot use push_back() with number"` +1. Throws [`type_error.308`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error308) when called on a type other than JSON object or null; example: `"cannot use push_back() with number"` +1. Throws [`type_error.308`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error308) when called on a type other than JSON array or null; example: `"cannot use push_back() with number"` + +## Complexity + +1. Amortized constant. +1. Logarithmic in the size of the container, O(log(`size()`)). +1. Linear in the size of the initializer list `init`. + +## Notes + +(3) This function is required to resolve an ambiguous overload error, because pairs like `{"key", "value"}` can be both interpreted as `object_t::value_type` or `std::initializer_list`, see [#235](https://github.com/nlohmann/json/issues/235) for more information. + +## Examples + +Example: (1) add element to array + +The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value was silently converted to a JSON array. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json array = {1, 2, 3, 4, 5}; + json null; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; + + // add values + array.push_back(6); + array += 7; + null += "first"; + null += "second"; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; +} +``` + +Output: + +``` +[1,2,3,4,5] +null +[1,2,3,4,5,6,7] +["first","second"] +``` + +Example: (2) add element to object + +The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value was silently converted to a JSON object. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values + object.push_back(json::object_t::value_type("three", 3)); + object += json::object_t::value_type("four", 4); + null += json::object_t::value_type("A", "a"); + null += json::object_t::value_type("B", "b"); + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; +} +``` + +Output: + +``` +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +{"A":"a","B":"b"} +``` + +Example: (3) add to object from initializer list + +The example shows how initializer lists are treated as objects when possible. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values: + object.push_back({"three", 3}); // object is extended + object += {"four", 4}; // object is extended + null.push_back({"five", 5}); // null is converted to array + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // would throw: + //object.push_back({1, 2, 3}); +} +``` + +Output: + +``` +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +[["five",5]] +``` + +## See also + +- [emplace_back](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) add a value to an array +- [push_back](https://json.nlohmann.me/api/basic_json/push_back/index.md) add a value to an array/object + +## Version history + +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 2.0.0. diff --git a/api/basic_json/operator=/index.html b/api/basic_json/operator=/index.html index 79377601e..16c20d9f3 100644 --- a/api/basic_json/operator=/index.html +++ b/api/basic_json/operator=/index.html @@ -25,4 +25,4 @@ }

Output:

23
 23
-

See also

  • basic_json create a JSON value
  • swap exchanges the contents of two JSON values

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

  • basic_json create a JSON value
  • swap exchanges the contents of two JSON values

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/operator=/index.md b/api/basic_json/operator=/index.md new file mode 100644 index 000000000..947a23825 --- /dev/null +++ b/api/basic_json/operator=/index.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::operator= + +``` +basic_json& operator=(basic_json other) noexcept ( + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_assignable::value +); +``` + +Copy assignment operator. Copies a JSON value via the "copy and swap" strategy: It is expressed in terms of the copy constructor, destructor, and the `swap()` member function. + +## Parameters + +`other` (in) : value to copy from + +## Exception safety + +Strong guarantee: if an exception is thrown while copying `other`, there are no changes to `*this`. + +## Complexity + +Linear. + +## Examples + +Example + +The code below shows and example for the copy assignment. It creates a copy of value `a` which is then swapped with `b`. Finally, the copy of `a` (which is the null value after the swap) is destroyed. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json a = 23; + json b = 42; + + // copy-assign a to b + b = a; + + // serialize the JSON arrays + std::cout << a << '\n'; + std::cout << b << '\n'; +} +``` + +Output: + +``` +23 +23 +``` + +## See also + +- [basic_json](https://json.nlohmann.me/api/basic_json/basic_json/index.md) create a JSON value +- [swap](https://json.nlohmann.me/api/basic_json/swap/index.md) exchanges the contents of two JSON values + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/operator[]/index.html b/api/basic_json/operator[]/index.html index 57ff3f03f..bca5b52e1 100644 --- a/api/basic_json/operator[]/index.html +++ b/api/basic_json/operator[]/index.html @@ -283,4 +283,4 @@ "foo" [1,2] 2 -

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0. Added overloads for T* key in version 1.1.0. Removed overloads for T* key (replaced by 3) in version 3.11.0.
  3. Added in version 3.11.0.
  4. Added in version 2.0.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0.
  2. Added in version 1.0.0. Added overloads for T* key in version 1.1.0. Removed overloads for T* key (replaced by 3) in version 3.11.0.
  3. Added in version 3.11.0.
  4. Added in version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/operator[]/index.md b/api/basic_json/operator[]/index.md new file mode 100644 index 000000000..542af2088 --- /dev/null +++ b/api/basic_json/operator[]/index.md @@ -0,0 +1,480 @@ +# nlohmann::basic_json::operator[] + +``` +// (1) +reference operator[](size_type idx); +const_reference operator[](size_type idx) const; + +// (2) +reference operator[](typename object_t::key_type key); +const_reference operator[](const typename object_t::key_type& key) const; + +// (3) +template +reference operator[](KeyType&& key); +template +const_reference operator[](KeyType&& key) const; + +// (4) +reference operator[](const json_pointer& ptr); +const_reference operator[](const json_pointer& ptr) const; +``` + +1. Returns a reference to the array element at specified location `idx`. +1. Returns a reference to the object element with specified key `key`. The non-const qualified overload takes the key by value. +1. See 2. This overload is only available if `KeyType` is comparable with `typename object_t::key_type` and `typename object_comparator_t::is_transparent` denotes a type. +1. Returns a reference to the element with specified JSON pointer `ptr`. + +## Template parameters + +`KeyType` : A type for an object key other than [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) that is comparable with [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) using [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). This can also be a string view (C++17). + +## Iterator invalidation + +For the non-const versions 1. and 4., when passing an **array** index that does not exist, it is created and filled with a `null` value before a reference to it is returned. For this, a reallocation can happen, in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. + +For [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), also passing an **object key** to the non-const versions 2., 3., and 4., a reallocation can happen which again invalidates all iterators and all references. + +## Parameters + +`idx` (in) : index of the element to access + +`key` (in) : object key of the element to access + +`ptr` (in) : JSON pointer to the desired element + +## Return value + +1. (const) reference to the element at index `idx` +1. (const) reference to the element at key `key` +1. (const) reference to the element at key `key` +1. (const) reference to the element pointed to by `ptr` + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.305`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error305) if the JSON value is not an array or null; in that case, using the `[]` operator with an index makes no sense. +1. The function can throw the following exceptions: + - Throws [`type_error.305`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error305) if the JSON value is not an object or null; in that case, using the `[]` operator with a key makes no sense. +1. See 2. +1. The function can throw the following exceptions: + - Throws [`parse_error.106`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error106) if an array index in the passed JSON pointer `ptr` begins with '0'. + - Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) if an array index in the passed JSON pointer `ptr` is not a number. + - Throws [`out_of_range.402`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range402) if the array index '-' is used in the passed JSON pointer `ptr` for the const version. + - Throws [`out_of_range.404`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range404) if the JSON pointer `ptr` can not be resolved. + - Throws [`out_of_range.410`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range410) if an array index in the passed JSON pointer `ptr` exceeds the range of `size_type` (e.g., on 32-bit platforms). + +## Complexity + +1. Constant if `idx` is in the range of the array. Otherwise, linear in `idx - size()`. +1. Logarithmic in the size of the container. +1. Logarithmic in the size of the container. +1. Logarithmic in the size of the container. + +## Notes + +Undefined behavior and runtime assertions + +The following cases apply to the **const** overloads; the non-const overloads instead insert the missing element (see the notes below). + +1. If the element at index `idx` does not exist, the behavior is undefined. + +1. If the element with key `key` does not exist, the behavior is undefined and is **guarded by a [runtime assertion](https://json.nlohmann.me/features/assertions/index.md)**! + +1. The non-const version may add values: If `idx` is beyond the range of the array (i.e., `idx >= size()`), then the array is silently filled up with `null` values to make `idx` a valid reference to the last stored element. In case the value was `null` before, it is converted to an array. + +1. If `key` is not found in the object, then it is silently added to the object and filled with a `null` value to make `key` a valid reference. In case the value was `null` before, it is converted to an object. + +1. See 2. + +1. `null` values are created in arrays and objects if necessary. + + In particular: + + - If the JSON pointer points to an object key that does not exist, it is created and filled with a `null` value before a reference to it is returned. + - If the JSON pointer points to an array index that does not exist, it is created and filled with a `null` value before a reference to it is returned. All indices between the current maximum and the given index are also filled with `null`. + - The special value `-` is treated as a synonym for the index past the end. + +## Examples + +Example: (1) access specified array element + +The example below shows how array elements can be read and written using `[]` operator. Note the addition of `null` values. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON array + json array = {1, 2, 3, 4, 5}; + + // output element at index 3 (fourth element) + std::cout << array[3] << '\n'; + + // change last element to 6 + array[array.size() - 1] = 6; + + // output changed array + std::cout << array << '\n'; + + // write beyond array limit + array[10] = 11; + + // output changed array + std::cout << array << '\n'; +} +``` + +Output: + +``` +4 +[1,2,3,4,6] +[1,2,3,4,6,null,null,null,null,null,11] +``` + +Example: (1) access specified array element (const) + +The example below shows how array elements can be read using the `[]` operator. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON array + const json array = {"first", "2nd", "third", "fourth"}; + + // output element at index 2 (third element) + std::cout << array.at(2) << '\n'; +} +``` + +Output: + +``` +"third" +``` + +Example: (2) access specified object element + +The example below shows how object elements can be read and written using the `[]` operator. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"] << "\n\n"; + + // change element with key "three" + object["three"] = 3; + + // output changed array + std::cout << std::setw(4) << object << "\n\n"; + + // mention nonexisting key + object["four"]; + + // write to nonexisting key + object["five"]["really"]["nested"] = true; + + // output changed object + std::cout << std::setw(4) << object << '\n'; +} +``` + +Output: + +``` +2 + +{ + "one": 1, + "three": 3, + "two": 2 +} + +{ + "five": { + "really": { + "nested": true + } + }, + "four": null, + "one": 1, + "three": 3, + "two": 2 +} +``` + +Example: (2) access specified object element (const) + +The example below shows how object elements can be read using the `[]` operator. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + const json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"] << '\n'; +} +``` + +Output: + +``` +2 +``` + +Example: (3) access specified object element using string_view + +The example below shows how object elements can be read using the `[]` operator. + +``` +#include +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"sv] << "\n\n"; + + // change element with key "three" + object["three"sv] = 3; + + // output changed array + std::cout << std::setw(4) << object << "\n\n"; + + // mention nonexisting key + object["four"sv]; + + // write to nonexisting key + object["five"sv]["really"sv]["nested"sv] = true; + + // output changed object + std::cout << std::setw(4) << object << '\n'; +} +``` + +Output: + +``` +2 + +{ + "one": 1, + "three": 3, + "two": 2 +} + +{ + "five": { + "really": { + "nested": true + } + }, + "four": null, + "one": 1, + "three": 3, + "two": 2 +} +``` + +Example: (3) access specified object element using string_view (const) + +The example below shows how object elements can be read using the `[]` operator. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object + const json object = + { + {"one", 1}, {"two", 2}, {"three", 2.9} + }; + + // output element with key "two" + std::cout << object["two"sv] << '\n'; +} +``` + +Output: + +``` +2 +``` + +Example: (4) access specified element via JSON Pointer + +The example below shows how values can be read and written using JSON Pointers. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j["/number"_json_pointer] << '\n'; + // output element with JSON pointer "/string" + std::cout << j["/string"_json_pointer] << '\n'; + // output element with JSON pointer "/array" + std::cout << j["/array"_json_pointer] << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j["/array/1"_json_pointer] << '\n'; + + // writing access + + // change the string + j["/string"_json_pointer] = "bar"; + // output the changed string + std::cout << j["string"] << '\n'; + + // "change" a nonexisting object entry + j["/boolean"_json_pointer] = true; + // output the changed object + std::cout << j << '\n'; + + // change an array element + j["/array/1"_json_pointer] = 21; + // "change" an array element with nonexisting index + j["/array/4"_json_pointer] = 44; + // output the changed array + std::cout << j["array"] << '\n'; + + // "change" the array element past the end + j["/array/-"_json_pointer] = 55; + // output the changed array + std::cout << j["array"] << '\n'; +} +``` + +Output: + +``` +1 +"foo" +[1,2] +2 +"bar" +{"array":[1,2],"boolean":true,"number":1,"string":"bar"} +[1,21,null,null,44] +[1,21,null,null,44,55] +``` + +Example: (4) access specified element via JSON Pointer (const) + +The example below shows how values can be read using JSON Pointers. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + const json j = + { + {"number", 1}, {"string", "foo"}, {"array", {1, 2}} + }; + + // read-only access + + // output element with JSON pointer "/number" + std::cout << j["/number"_json_pointer] << '\n'; + // output element with JSON pointer "/string" + std::cout << j["/string"_json_pointer] << '\n'; + // output element with JSON pointer "/array" + std::cout << j["/array"_json_pointer] << '\n'; + // output element with JSON pointer "/array/1" + std::cout << j["/array/1"_json_pointer] << '\n'; +} +``` + +Output: + +``` +1 +"foo" +[1,2] +2 +``` + +## See also + +- documentation on [unchecked access](https://json.nlohmann.me/features/element_access/unchecked_access/index.md) +- documentation on [runtime assertions](https://json.nlohmann.me/features/assertions/index.md) +- see [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) for access by reference with range checking +- see [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) for access with default value + +## Version history + +1. Added in version 1.0.0. +1. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3) in version 3.11.0. +1. Added in version 3.11.0. +1. Added in version 2.0.0. diff --git a/api/basic_json/operator_ValueType.md b/api/basic_json/operator_ValueType.md new file mode 100644 index 000000000..231a33df4 --- /dev/null +++ b/api/basic_json/operator_ValueType.md @@ -0,0 +1,87 @@ +# nlohmann::basic_json::operator ValueType + +```cpp +template +JSON_EXPLICIT operator ValueType() const; +``` + +Implicit type conversion between the JSON value and a compatible value. The call is realized by calling +[`get()`](get.md). See [Notes](#notes) for the meaning of `JSON_EXPLICIT`. + +## Template parameters + +`ValueType` +: the value type to return + +## Return value + +copy of the JSON value, converted to `ValueType` + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +!!! note "Definition of `JSON_EXPLICIT`" + + By default `JSON_EXPLICIT` is defined to the empty string, so the signature is: + + ```cpp + template + operator ValueType() const; + ``` + + If [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) is set to `0`, + `JSON_EXPLICIT` is defined to `#!cpp explicit`: + + ```cpp + template + explicit operator ValueType() const; + ``` + + That is, implicit conversions can be switched off by defining + [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) to `0`. + +!!! info "Future behavior change" + + Implicit conversions will be switched off by default in the next major release of the library. That is, + `JSON_EXPLICIT` will be set to `#!cpp explicit` by default. + + You can prepare existing code by already defining + [`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) to `0` and replace any implicit + conversions with calls to [`get`](../basic_json/get.md). + +## Examples + +??? example + + The example below shows several conversions from JSON values to other types. There are a few things to note: (1) + Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard + `std::vector`, (3) A JSON object can be converted to C++ associative containers such as + `std::unordered_map`. + + ```cpp + --8<-- "examples/operator__ValueType.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__ValueType.output" + ``` + +## See also + +- [get](get.md) get a value (explicit conversion) +- [Converting values](../../features/conversions.md) - the type conversions article + +## Version history + +- Since version 1.0.0. +- Macros `JSON_EXPLICIT`/[`JSON_USE_IMPLICIT_CONVERSIONS`](../macros/json_use_implicit_conversions.md) added + in version 3.9.0. diff --git a/api/basic_json/operator_ValueType/index.html b/api/basic_json/operator_ValueType/index.html index f3c850b71..30a5b6696 100644 --- a/api/basic_json/operator_ValueType/index.html +++ b/api/basic_json/operator_ValueType/index.html @@ -76,4 +76,4 @@ boolean: true array: [1,2,3,4,5] [json.exception.type_error.302] type must be boolean, but is string -

See also

Version history

\ No newline at end of file +

See also

Version history

\ No newline at end of file diff --git a/api/basic_json/operator_ValueType/index.md b/api/basic_json/operator_ValueType/index.md new file mode 100644 index 000000000..83d9d289a --- /dev/null +++ b/api/basic_json/operator_ValueType/index.md @@ -0,0 +1,146 @@ +# nlohmann::basic_json::operator ValueType + +``` +template +JSON_EXPLICIT operator ValueType() const; +``` + +Implicit type conversion between the JSON value and a compatible value. The call is realized by calling [`get()`](https://json.nlohmann.me/api/basic_json/get/index.md). See [Notes](#notes) for the meaning of `JSON_EXPLICIT`. + +## Template parameters + +`ValueType` : the value type to return + +## Return value + +copy of the JSON value, converted to `ValueType` + +## Exceptions + +Depends on what `json_serializer` `from_json()` method throws + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +Definition of `JSON_EXPLICIT` + +By default `JSON_EXPLICIT` is defined to the empty string, so the signature is: + +``` +template +operator ValueType() const; +``` + +If [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) is set to `0`, `JSON_EXPLICIT` is defined to `explicit`: + +``` +template +explicit operator ValueType() const; +``` + +That is, implicit conversions can be switched off by defining [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) to `0`. + +Future behavior change + +Implicit conversions will be switched off by default in the next major release of the library. That is, `JSON_EXPLICIT` will be set to `explicit` by default. + +You can prepare existing code by already defining [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) to `0` and replace any implicit conversions with calls to [`get`](https://json.nlohmann.me/api/basic_json/get/index.md). + +## Examples + +Example + +The example below shows several conversions from JSON values to other types. There are a few things to note: (1) Floating-point numbers can be converted to integers, (2) A JSON array can be converted to a standard `std::vector`, (3) A JSON object can be converted to C++ associative containers such as `std::unordered_map`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + // use implicit conversions + bool v1 = json_types["boolean"]; + int v2 = json_types["number"]["integer"]; + short v3 = json_types["number"]["integer"]; + float v4 = json_types["number"]["floating-point"]; + int v5 = json_types["number"]["floating-point"]; + std::string v6 = json_types["string"]; + std::vector v7 = json_types["array"]; + std::unordered_map v8 = json_types; + + // print the conversion results + std::cout << v1 << '\n'; + std::cout << v2 << ' ' << v3 << '\n'; + std::cout << v4 << ' ' << v5 << '\n'; + std::cout << v6 << '\n'; + + for (auto i : v7) + { + std::cout << i << ' '; + } + std::cout << "\n\n"; + + for (auto i : v8) + { + std::cout << i.first << ": " << i.second << '\n'; + } + + // example for an exception + try + { + bool v1 = json_types["string"]; + } + catch (const json::type_error& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +1 +42 42 +17.23 17 +Hello, world! +1 2 3 4 5 + +string: "Hello, world!" +number: {"floating-point":17.23,"integer":42} +null: null +boolean: true +array: [1,2,3,4,5] +[json.exception.type_error.302] type must be boolean, but is string +``` + +## See also + +- [get](https://json.nlohmann.me/api/basic_json/get/index.md) get a value (explicit conversion) +- [Converting values](https://json.nlohmann.me/features/conversions/index.md) - the type conversions article + +## Version history + +- Since version 1.0.0. +- Macros `JSON_EXPLICIT`/[`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) added in version 3.9.0. diff --git a/api/basic_json/operator_eq.md b/api/basic_json/operator_eq.md new file mode 100644 index 000000000..b575622d1 --- /dev/null +++ b/api/basic_json/operator_eq.md @@ -0,0 +1,173 @@ +# nlohmann::basic_json::operator== + +```cpp +// until C++20 +bool operator==(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator==(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator==(ScalarType lhs, const const_reference rhs) noexcept; // (2) + +// since C++20 +class basic_json { + bool operator==(const_reference rhs) const noexcept; // (1) + + template + bool operator==(ScalarType rhs) const noexcept; // (2) +}; +``` + +1. Compares two JSON values for equality according to the following rules: + - Two JSON values are equal if (1) neither value is discarded, and (2) they are of the same type and their stored + values are the same according to their respective `operator==`. + - Integer and floating-point numbers are automatically converted before comparison. + +2. Compares a JSON value and a scalar or a scalar and a JSON value for equality by converting the + scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are equal + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing special values" + + - `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + - JSON `#!cpp null` values are all equal. + - Discarded values never compare equal to themselves. + +!!! note "Comparing floating-point numbers" + + Floating-point numbers inside JSON values numbers are compared with `json::number_float_t::operator==` which is + `double::operator==` by default. To compare floating-point while respecting an epsilon, an alternative + [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) + could be used, for instance + + ```cpp + template::value, T>::type> + inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept + { + return std::abs(a - b) <= epsilon; + } + ``` + + Or you can define your own equality function like this: + + ```cpp + bool my_equal(const_reference lhs, const_reference rhs) + { + const auto lhs_type = lhs.type(); + const auto rhs_type = rhs.type(); + if (lhs_type == rhs_type) + { + switch(lhs_type) + // self_defined case + case value_t::number_float: + return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); + // other cases remain the same with the original + ... + } + ... + } + ``` + +!!! note "Comparing different `basic_json` specializations" + + Comparing different `basic_json` specializations can have surprising effects. For instance, the result of comparing + the JSON objects + + ```json + { + "version": 1, + "type": "integer" + } + ``` + + and + + ```json + { + "type": "integer", + "version": 1 + } + ``` + + depends on whether [`nlohmann::json`](../json.md) or [`nlohmann::ordered_json`](../ordered_json.md) is used: + + ```cpp + --8<-- "examples/operator__equal__specializations.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__equal__specializations.output" + ``` + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__equal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__equal.output" + ``` + +??? example + + The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`). + + ```cpp + --8<-- "examples/operator__equal__nullptr_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__equal__nullptr_t.output" + ``` + +## See also + +- [operator!=](operator_ne.md) compare for inequality +- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20) + +## Version history + +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. +2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. diff --git a/api/basic_json/operator_eq/index.html b/api/basic_json/operator_eq/index.html index 0dd19c6b1..bd84a188d 100644 --- a/api/basic_json/operator_eq/index.html +++ b/api/basic_json/operator_eq/index.html @@ -115,4 +115,4 @@ 17 == nullptr false "foo" == nullptr false null == nullptr true -

See also

Version history

  1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
  2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
  2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/operator_eq/index.md b/api/basic_json/operator_eq/index.md new file mode 100644 index 000000000..eaed7a814 --- /dev/null +++ b/api/basic_json/operator_eq/index.md @@ -0,0 +1,231 @@ +# nlohmann::basic_json::operator== + +``` +// until C++20 +bool operator==(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator==(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator==(ScalarType lhs, const const_reference rhs) noexcept; // (2) + +// since C++20 +class basic_json { + bool operator==(const_reference rhs) const noexcept; // (1) + + template + bool operator==(ScalarType rhs) const noexcept; // (2) +}; +``` + +1. Compares two JSON values for equality according to the following rules: + + - Two JSON values are equal if (1) neither value is discarded, and (2) they are of the same type and their stored values are the same according to their respective `operator==`. + - Integer and floating-point numbers are automatically converted before comparison. + +1. Compares a JSON value and a scalar or a scalar and a JSON value for equality by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` : a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are equal + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +Comparing special values + +- `NaN` values are unordered within the domain of numbers. The following comparisons all yield `false`: + 1. Comparing a `NaN` with itself. + 1. Comparing a `NaN` with another `NaN`. + 1. Comparing a `NaN` and any other number. +- JSON `null` values are all equal. +- Discarded values never compare equal to themselves. + +Comparing floating-point numbers + +Floating-point numbers inside JSON values numbers are compared with `json::number_float_t::operator==` which is `double::operator==` by default. To compare floating-point while respecting an epsilon, an alternative [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) could be used, for instance + +``` +template::value, T>::type> +inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept +{ + return std::abs(a - b) <= epsilon; +} +``` + +Or you can define your own equality function like this: + +``` +bool my_equal(const_reference lhs, const_reference rhs) +{ + const auto lhs_type = lhs.type(); + const auto rhs_type = rhs.type(); + if (lhs_type == rhs_type) + { + switch(lhs_type) + // self_defined case + case value_t::number_float: + return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); + // other cases remain the same with the original + ... + } +... +} +``` + +Comparing different `basic_json` specializations + +Comparing different `basic_json` specializations can have surprising effects. For instance, the result of comparing the JSON objects + +``` +{ + "version": 1, + "type": "integer" +} +``` + +and + +``` +{ + "type": "integer", + "version": 1 +} +``` + +depends on whether [`nlohmann::json`](https://json.nlohmann.me/api/json/index.md) or [`nlohmann::ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) is used: + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + nlohmann::json uj1 = {{"version", 1}, {"type", "integer"}}; + nlohmann::json uj2 = {{"type", "integer"}, {"version", 1}}; + + nlohmann::ordered_json oj1 = {{"version", 1}, {"type", "integer"}}; + nlohmann::ordered_json oj2 = {{"type", "integer"}, {"version", 1}}; + + std::cout << std::boolalpha << (uj1 == uj2) << '\n' << (oj1 == oj2) << std::endl; +} +``` + +Output: + +``` +true +false +``` + +## Examples + +Example + +The example demonstrates comparing several JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.000000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 == array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 == object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 == number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 == string_2) << '\n'; +} +``` + +Output: + +``` +[1,2,3] == [1,2,4] false +{"A":"a","B":"b"} == {"A":"a","B":"b"} true +17 == 17.0 true +"foo" == "bar" false +``` + +Example + +The example demonstrates comparing several JSON types against the null pointer (JSON `null`). + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array = {1, 2, 3}; + json object = {{"A", "a"}, {"B", "b"}}; + json number = 17; + json string = "foo"; + json null; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array << " == nullptr " << (array == nullptr) << '\n'; + std::cout << object << " == nullptr " << (object == nullptr) << '\n'; + std::cout << number << " == nullptr " << (number == nullptr) << '\n'; + std::cout << string << " == nullptr " << (string == nullptr) << '\n'; + std::cout << null << " == nullptr " << (null == nullptr) << '\n'; +} +``` + +Output: + +``` +[1,2,3] == nullptr false +{"A":"a","B":"b"} == nullptr false +17 == nullptr false +"foo" == nullptr false +null == nullptr true +``` + +## See also + +- [operator!=](https://json.nlohmann.me/api/basic_json/operator_ne/index.md) compare for inequality +- [operator\<=>](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) comparison: 3-way (C++20) + +## Version history + +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. diff --git a/api/basic_json/operator_ge.md b/api/basic_json/operator_ge.md new file mode 100644 index 000000000..9ae6ada86 --- /dev/null +++ b/api/basic_json/operator_ge.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::operator>= + +```cpp +// until C++20 +bool operator>=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator>=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator>=(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is greater than or equal to another JSON value `rhs` according to the following + rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either operand is `NaN` and + the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(lhs < rhs)` (see [**operator<**](operator_lt.md)). + +2. Compares whether a JSON value is greater than or equal to a scalar or a scalar is greater than or equal to a JSON + value by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is greater than or equal to `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__greaterequal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__greaterequal.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_ge/index.html b/api/basic_json/operator_ge/index.html index 8c5bb9beb..a770c6820 100644 --- a/api/basic_json/operator_ge/index.html +++ b/api/basic_json/operator_ge/index.html @@ -34,4 +34,4 @@ {"A":"a","B":"b"} >= {"A":"a","B":"b"} true 17 >= 17.0000000000001 false "foo" >= "bar" true -

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/operator_ge/index.md b/api/basic_json/operator_ge/index.md new file mode 100644 index 000000000..60e8a496b --- /dev/null +++ b/api/basic_json/operator_ge/index.md @@ -0,0 +1,106 @@ +# nlohmann::basic_json::operator>= + +``` +// until C++20 +bool operator>=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator>=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator>=(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is greater than or equal to another JSON value `rhs` according to the following rules: + + - The comparison always yields `false` if (1) either operand is discarded, or (2) either operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `!(lhs < rhs)` (see [**operator\<**](https://json.nlohmann.me/api/basic_json/operator_lt/index.md)). + +1. Compares whether a JSON value is greater than or equal to a scalar or a scalar is greater than or equal to a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` : a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether `lhs` is greater than or equal to `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +Comparing `NaN` + +`NaN` values are unordered within the domain of numbers. The following comparisons all yield `false`: + +1. Comparing a `NaN` with itself. +1. Comparing a `NaN` with another `NaN`. +1. Comparing a `NaN` and any other number. + +Operator overload resolution + +Since C++20 overload resolution will consider the *rewritten candidate* generated from [`operator<=>`](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md). + +## Examples + +Example + +The example demonstrates comparing several JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " >= " << array_2 << " " << (array_1 >= array_2) << '\n'; + std::cout << object_1 << " >= " << object_2 << " " << (object_1 >= object_2) << '\n'; + std::cout << number_1 << " >= " << number_2 << " " << (number_1 >= number_2) << '\n'; + std::cout << string_1 << " >= " << string_2 << " " << (string_1 >= string_2) << '\n'; +} +``` + +Output: + +``` +[1,2,3] >= [1,2,4] false +{"A":"a","B":"b"} >= {"A":"a","B":"b"} true +17 >= 17.0000000000001 false +"foo" >= "bar" true +``` + +## See also + +- [**operator\<=>**](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_gt.md b/api/basic_json/operator_gt.md new file mode 100644 index 000000000..486da5fd0 --- /dev/null +++ b/api/basic_json/operator_gt.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::operator> + +```cpp +// until C++20 +bool operator>(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator>(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator>(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is greater than another JSON value `rhs` according to the + following rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either + operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(lhs <= rhs)` (see [**operator<=**](operator_le.md)). + +2. Compares whether a JSON value is greater than a scalar or a scalar is greater than a JSON value by + converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is greater than `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__greater.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__greater.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_gt/index.html b/api/basic_json/operator_gt/index.html index d9639b97c..8b6942f66 100644 --- a/api/basic_json/operator_gt/index.html +++ b/api/basic_json/operator_gt/index.html @@ -34,4 +34,4 @@ {"A":"a","B":"b"} > {"A":"a","B":"b"} false 17 > 17.0000000000001 false "foo" > "bar" true -

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/operator_gt/index.md b/api/basic_json/operator_gt/index.md new file mode 100644 index 000000000..2d6852e70 --- /dev/null +++ b/api/basic_json/operator_gt/index.md @@ -0,0 +1,106 @@ +# nlohmann::basic_json::operator> + +``` +// until C++20 +bool operator>(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator>(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator>(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is greater than another JSON value `rhs` according to the following rules: + + - The comparison always yields `false` if (1) either operand is discarded, or (2) either operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `!(lhs <= rhs)` (see [**operator\<=**](https://json.nlohmann.me/api/basic_json/operator_le/index.md)). + +1. Compares whether a JSON value is greater than a scalar or a scalar is greater than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` : a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether `lhs` is greater than `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +Comparing `NaN` + +`NaN` values are unordered within the domain of numbers. The following comparisons all yield `false`: + +1. Comparing a `NaN` with itself. +1. Comparing a `NaN` with another `NaN`. +1. Comparing a `NaN` and any other number. + +Operator overload resolution + +Since C++20 overload resolution will consider the *rewritten candidate* generated from [`operator<=>`](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md). + +## Examples + +Example + +The example demonstrates comparing several JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " > " << array_2 << " " << (array_1 > array_2) << '\n'; + std::cout << object_1 << " > " << object_2 << " " << (object_1 > object_2) << '\n'; + std::cout << number_1 << " > " << number_2 << " " << (number_1 > number_2) << '\n'; + std::cout << string_1 << " > " << string_2 << " " << (string_1 > string_2) << '\n'; +} +``` + +Output: + +``` +[1,2,3] > [1,2,4] false +{"A":"a","B":"b"} > {"A":"a","B":"b"} false +17 > 17.0000000000001 false +"foo" > "bar" true +``` + +## See also + +- [**operator\<=>**](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_le.md b/api/basic_json/operator_le.md new file mode 100644 index 000000000..9dfa4e1e0 --- /dev/null +++ b/api/basic_json/operator_le.md @@ -0,0 +1,87 @@ +# nlohmann::basic_json::operator<= + +```cpp +// until C++20 +bool operator<=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator<=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator<=(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is less than or equal to another JSON value `rhs` + according to the following rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either + operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(rhs < lhs)` (see [**operator<**](operator_lt.md)). + +2. Compares whether a JSON value is less than or equal to a scalar or a scalar is less than or equal + to a JSON value by converting the scalar to a JSON value and comparing both JSON values according + to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is less than or equal to `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__lessequal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__lessequal.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_le/index.html b/api/basic_json/operator_le/index.html index 8f1299dc4..81b6d65d2 100644 --- a/api/basic_json/operator_le/index.html +++ b/api/basic_json/operator_le/index.html @@ -34,4 +34,4 @@ {"A":"a","B":"b"} <= {"A":"a","B":"b"} true 17 <= 17.0000000000001 true "foo" <= "bar" false -

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/operator_le/index.md b/api/basic_json/operator_le/index.md new file mode 100644 index 000000000..119344f31 --- /dev/null +++ b/api/basic_json/operator_le/index.md @@ -0,0 +1,106 @@ +# nlohmann::basic_json::operator\<= + +``` +// until C++20 +bool operator<=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator<=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator<=(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is less than or equal to another JSON value `rhs` according to the following rules: + + - The comparison always yields `false` if (1) either operand is discarded, or (2) either operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `!(rhs < lhs)` (see [**operator\<**](https://json.nlohmann.me/api/basic_json/operator_lt/index.md)). + +1. Compares whether a JSON value is less than or equal to a scalar or a scalar is less than or equal to a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` : a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether `lhs` is less than or equal to `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +Comparing `NaN` + +`NaN` values are unordered within the domain of numbers. The following comparisons all yield `false`: + +1. Comparing a `NaN` with itself. +1. Comparing a `NaN` with another `NaN`. +1. Comparing a `NaN` and any other number. + +Operator overload resolution + +Since C++20 overload resolution will consider the *rewritten candidate* generated from [`operator<=>`](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md). + +## Examples + +Example + +The example demonstrates comparing several JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " <= " << array_2 << " " << (array_1 <= array_2) << '\n'; + std::cout << object_1 << " <= " << object_2 << " " << (object_1 <= object_2) << '\n'; + std::cout << number_1 << " <= " << number_2 << " " << (number_1 <= number_2) << '\n'; + std::cout << string_1 << " <= " << string_2 << " " << (string_1 <= string_2) << '\n'; +} +``` + +Output: + +``` +[1,2,3] <= [1,2,4] true +{"A":"a","B":"b"} <= {"A":"a","B":"b"} true +17 <= 17.0000000000001 true +"foo" <= "bar" false +``` + +## See also + +- [**operator\<=>**](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_lt.md b/api/basic_json/operator_lt.md new file mode 100644 index 000000000..118d817c8 --- /dev/null +++ b/api/basic_json/operator_lt.md @@ -0,0 +1,96 @@ +# nlohmann::basic_json::operator< + +```cpp +// until C++20 +bool operator<(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator<(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator<(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is less than another JSON value `rhs` according to the + following rules: + - If either operand is discarded, the comparison yields `#!cpp false`. + - If both operands have the same type, the values are compared using their respective `operator<`. + - Integer and floating-point numbers are automatically converted before comparison. + - In case `lhs` and `rhs` have different types, the values are ignored and the order of the types + is considered, which is: + 1. null + 2. boolean + 3. number (all types) + 4. object + 5. array + 6. string + 7. binary + For instance, any boolean value is considered less than any string. + +2. Compares whether a JSON value is less than a scalar or a scalar is less than a JSON value by converting + the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether `lhs` is less than `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator<=>`](operator_spaceship.md). + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__less.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__less.output" + ``` + +## See also + +- [**operator<=>**](operator_spaceship.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_lt/index.html b/api/basic_json/operator_lt/index.html index ee2a146da..eea28cb33 100644 --- a/api/basic_json/operator_lt/index.html +++ b/api/basic_json/operator_lt/index.html @@ -34,4 +34,4 @@ {"A":"a","B":"b"} == {"A":"a","B":"b"} false 17 == 17.0000000000001 true "foo" == "bar" false -

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
  2. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/operator_lt/index.md b/api/basic_json/operator_lt/index.md new file mode 100644 index 000000000..f68efc79f --- /dev/null +++ b/api/basic_json/operator_lt/index.md @@ -0,0 +1,115 @@ +# nlohmann::basic_json::operator\< + +``` +// until C++20 +bool operator<(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator<(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator<(ScalarType lhs, const const_reference rhs) noexcept; // (2) +``` + +1. Compares whether one JSON value `lhs` is less than another JSON value `rhs` according to the following rules: + + - If either operand is discarded, the comparison yields `false`. + - If both operands have the same type, the values are compared using their respective `operator<`. + - Integer and floating-point numbers are automatically converted before comparison. + - In case `lhs` and `rhs` have different types, the values are ignored and the order of the types is considered, which is: + 1. null + 1. boolean + 1. number (all types) + 1. object + 1. array + 1. string + 1. binary For instance, any boolean value is considered less than any string. + +1. Compares whether a JSON value is less than a scalar or a scalar is less than a JSON value by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` : a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether `lhs` is less than `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +Comparing `NaN` + +`NaN` values are unordered within the domain of numbers. The following comparisons all yield `false`: + +1. Comparing a `NaN` with itself. +1. Comparing a `NaN` with another `NaN`. +1. Comparing a `NaN` and any other number. + +Operator overload resolution + +Since C++20 overload resolution will consider the *rewritten candidate* generated from [`operator<=>`](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md). + +## Examples + +Example + +The example demonstrates comparing several JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.0000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " == " << array_2 << " " << (array_1 < array_2) << '\n'; + std::cout << object_1 << " == " << object_2 << " " << (object_1 < object_2) << '\n'; + std::cout << number_1 << " == " << number_2 << " " << (number_1 < number_2) << '\n'; + std::cout << string_1 << " == " << string_2 << " " << (string_1 < string_2) << '\n'; +} +``` + +Output: + +``` +[1,2,3] == [1,2,4] true +{"A":"a","B":"b"} == {"A":"a","B":"b"} false +17 == 17.0000000000001 true +"foo" == "bar" false +``` + +## See also + +- [**operator\<=>**](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) comparison: 3-way + +## Version history + +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. +1. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. diff --git a/api/basic_json/operator_ne.md b/api/basic_json/operator_ne.md new file mode 100644 index 000000000..982a06764 --- /dev/null +++ b/api/basic_json/operator_ne.md @@ -0,0 +1,98 @@ +# nlohmann::basic_json::operator!= + +```cpp +// until C++20 +bool operator!=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator!=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator!=(ScalarType lhs, const const_reference rhs) noexcept; // (2) + +// since C++20 +class basic_json { + bool operator!=(const_reference rhs) const noexcept; // (1) + + template + bool operator!=(ScalarType rhs) const noexcept; // (2) +}; +``` + +1. Compares two JSON values for inequality according to the following rules: + - The comparison always yields `#!cpp false` if (1) either operand is discarded, or (2) either operand is `NaN` and + the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `#!cpp !(lhs == rhs)` (until C++20) or `#!cpp !(*this == rhs)` (since C++20). + +2. Compares a JSON value and a scalar or a scalar and a JSON value for inequality by converting the scalar to a JSON + value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are not equal + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `#!cpp false`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +## Examples + +??? example + + The example demonstrates comparing several JSON types. + + ```cpp + --8<-- "examples/operator__notequal.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__notequal.output" + ``` + +??? example + + The example demonstrates comparing several JSON types against the null pointer (JSON `#!json null`). + + ```cpp + --8<-- "examples/operator__notequal__nullptr_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__notequal__nullptr_t.output" + ``` + +## Version history + +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. +2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. diff --git a/api/basic_json/operator_ne/index.html b/api/basic_json/operator_ne/index.html index 74cd71bc8..587477854 100644 --- a/api/basic_json/operator_ne/index.html +++ b/api/basic_json/operator_ne/index.html @@ -69,4 +69,4 @@ 17 != nullptr true "foo" != nullptr true null != nullptr false -

Version history

  1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
  2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
\ No newline at end of file +

Version history

  1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
  2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/operator_ne/index.md b/api/basic_json/operator_ne/index.md new file mode 100644 index 000000000..7933dc803 --- /dev/null +++ b/api/basic_json/operator_ne/index.md @@ -0,0 +1,145 @@ +# nlohmann::basic_json::operator!= + +``` +// until C++20 +bool operator!=(const_reference lhs, const_reference rhs) noexcept; // (1) + +template +bool operator!=(const_reference lhs, const ScalarType rhs) noexcept; // (2) + +template +bool operator!=(ScalarType lhs, const const_reference rhs) noexcept; // (2) + +// since C++20 +class basic_json { + bool operator!=(const_reference rhs) const noexcept; // (1) + + template + bool operator!=(ScalarType rhs) const noexcept; // (2) +}; +``` + +1. Compares two JSON values for inequality according to the following rules: + + - The comparison always yields `false` if (1) either operand is discarded, or (2) either operand is `NaN` and the other operand is either `NaN` or any other number. + - Otherwise, returns the result of `!(lhs == rhs)` (until C++20) or `!(*this == rhs)` (since C++20). + +1. Compares a JSON value and a scalar or a scalar and a JSON value for inequality by converting the scalar to a JSON value and comparing both JSON values according to 1. + +## Template parameters + +`ScalarType` : a scalar type according to `std::is_scalar::value` + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are not equal + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +Comparing `NaN` + +`NaN` values are unordered within the domain of numbers. The following comparisons all yield `false`: + +1. Comparing a `NaN` with itself. +1. Comparing a `NaN` with another `NaN`. +1. Comparing a `NaN` and any other number. + +## Examples + +Example + +The example demonstrates comparing several JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number_1 = 17; + json number_2 = 17.000000000000001L; + json string_1 = "foo"; + json string_2 = "bar"; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array_1 << " != " << array_2 << " " << (array_1 != array_2) << '\n'; + std::cout << object_1 << " != " << object_2 << " " << (object_1 != object_2) << '\n'; + std::cout << number_1 << " != " << number_2 << " " << (number_1 != number_2) << '\n'; + std::cout << string_1 << " != " << string_2 << " " << (string_1 != string_2) << '\n'; +} +``` + +Output: + +``` +[1,2,3] != [1,2,4] true +{"A":"a","B":"b"} != {"A":"a","B":"b"} false +17 != 17.0 false +"foo" != "bar" true +``` + +Example + +The example demonstrates comparing several JSON types against the null pointer (JSON `null`). + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create several JSON values + json array = {1, 2, 3}; + json object = {{"A", "a"}, {"B", "b"}}; + json number = 17; + json string = "foo"; + json null; + + // output values and comparisons + std::cout << std::boolalpha; + std::cout << array << " != nullptr " << (array != nullptr) << '\n'; + std::cout << object << " != nullptr " << (object != nullptr) << '\n'; + std::cout << number << " != nullptr " << (number != nullptr) << '\n'; + std::cout << string << " != nullptr " << (string != nullptr) << '\n'; + std::cout << null << " != nullptr " << (null != nullptr) << '\n'; +} +``` + +Output: + +``` +[1,2,3] != nullptr true +{"A":"a","B":"b"} != nullptr true +17 != nullptr true +"foo" != nullptr true +null != nullptr false +``` + +## Version history + +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. +1. Added in version 1.0.0. Added C++20 member functions in version 3.11.0. diff --git a/api/basic_json/operator_spaceship.md b/api/basic_json/operator_spaceship.md new file mode 100644 index 000000000..9e91d0d2d --- /dev/null +++ b/api/basic_json/operator_spaceship.md @@ -0,0 +1,100 @@ +# nlohmann::basic_json::operator<=> + +```cpp +// since C++20 +class basic_json { + std::partial_ordering operator<=>(const_reference rhs) const noexcept; // (1) + + template + std::partial_ordering operator<=>(const ScalarType rhs) const noexcept; // (2) +}; +``` + +1. 3-way compares two JSON values producing a result of type `std::partial_ordering` according to the following rules: + - Two JSON values compare with a result of `std::partial_ordering::unordered` if either value is discarded. + - If both JSON values are of the same type, the result is produced by 3-way comparing their stored values using + their respective `operator<=>`. + - Integer and floating-point numbers are converted to their common type and then 3-way compared using their + respective `operator<=>`. + For instance, comparing an integer and a floating-point value will 3-way compare the first value converted to + floating-point with the second value. + - Otherwise, yields a result by comparing the type (see [`value_t`](value_t.md)). + +2. 3-way compares a JSON value and a scalar or a scalar and a JSON value by converting the scalar to a JSON value and + 3-way comparing both JSON values (see 1). + +## Template parameters + +`ScalarType` +: a scalar type according to `std::is_scalar::value` + +## Parameters + +`rhs` (in) +: second value to consider + +## Return value + +the `std::partial_ordering` of the 3-way comparison of `*this` and `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +!!! note "Comparing `NaN`" + + - `NaN` values are unordered within the domain of numbers. + The following comparisons all yield `std::partial_ordering::unordered`: + 1. Comparing a `NaN` with itself. + 2. Comparing a `NaN` with another `NaN`. + 3. Comparing a `NaN` and any other number. + +## Examples + +??? example "Example: (1) comparing JSON values" + + The example demonstrates comparing several JSON values. + + ```cpp + --8<-- "examples/operator_spaceship__const_reference.c++20.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_spaceship__const_reference.c++20.output" + ``` + +??? example "Example: (2) comparing JSON values and scalars" + + The example demonstrates comparing several JSON values and scalars. + + ```cpp + --8<-- "examples/operator_spaceship__scalartype.c++20.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_spaceship__scalartype.c++20.output" + ``` + +## See also + +- [**operator==**](operator_eq.md) - comparison: equal +- [**operator!=**](operator_ne.md) - comparison: not equal +- [**operator<**](operator_lt.md) - comparison: less than +- [**operator<=**](operator_le.md) - comparison: less than or equal +- [**operator>**](operator_gt.md) - comparison: greater than +- [**operator>=**](operator_ge.md) - comparison: greater than or equal + +## Version history + +1. Added in version 3.11.0. +2. Added in version 3.11.0. diff --git a/api/basic_json/operator_spaceship/index.html b/api/basic_json/operator_spaceship/index.html index 22e3cc313..620745b0f 100644 --- a/api/basic_json/operator_spaceship/index.html +++ b/api/basic_json/operator_spaceship/index.html @@ -93,4 +93,4 @@ 17 <=> 17.000000 := equivalent 17 <=> nan := unordered "17" <=> 17 := greater -

See also

Version history

  1. Added in version 3.11.0.
  2. Added in version 3.11.0.
\ No newline at end of file +

See also

Version history

  1. Added in version 3.11.0.
  2. Added in version 3.11.0.
\ No newline at end of file diff --git a/api/basic_json/operator_spaceship/index.md b/api/basic_json/operator_spaceship/index.md new file mode 100644 index 000000000..269de6c25 --- /dev/null +++ b/api/basic_json/operator_spaceship/index.md @@ -0,0 +1,177 @@ +# nlohmann::basic_json::operator\<=> + +``` +// since C++20 +class basic_json { + std::partial_ordering operator<=>(const_reference rhs) const noexcept; // (1) + + template + std::partial_ordering operator<=>(const ScalarType rhs) const noexcept; // (2) +}; +``` + +1. 3-way compares two JSON values producing a result of type `std::partial_ordering` according to the following rules: + + - Two JSON values compare with a result of `std::partial_ordering::unordered` if either value is discarded. + - If both JSON values are of the same type, the result is produced by 3-way comparing their stored values using their respective `operator<=>`. + - Integer and floating-point numbers are converted to their common type and then 3-way compared using their respective `operator<=>`. For instance, comparing an integer and a floating-point value will 3-way compare the first value converted to floating-point with the second value. + - Otherwise, yields a result by comparing the type (see [`value_t`](https://json.nlohmann.me/api/basic_json/value_t/index.md)). + +1. 3-way compares a JSON value and a scalar or a scalar and a JSON value by converting the scalar to a JSON value and 3-way comparing both JSON values (see 1). + +## Template parameters + +`ScalarType` : a scalar type according to `std::is_scalar::value` + +## Parameters + +`rhs` (in) : second value to consider + +## Return value + +the `std::partial_ordering` of the 3-way comparison of `*this` and `rhs` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear. + +## Notes + +Comparing `NaN` + +- `NaN` values are unordered within the domain of numbers. The following comparisons all yield `std::partial_ordering::unordered`: + 1. Comparing a `NaN` with itself. + 1. Comparing a `NaN` with another `NaN`. + 1. Comparing a `NaN` and any other number. + +## Examples + +Example: (1) comparing JSON values + +The example demonstrates comparing several JSON values. + +``` +#include +#include +#include + +using json = nlohmann::json; + +const char* to_string(const std::partial_ordering& po) +{ + if (std::is_lt(po)) + { + return "less"; + } + else if (std::is_gt(po)) + { + return "greater"; + } + else if (std::is_eq(po)) + { + return "equivalent"; + } + return "unordered"; +} + +int main() +{ + // create several JSON values + json array_1 = {1, 2, 3}; + json array_2 = {1, 2, 4}; + json object_1 = {{"A", "a"}, {"B", "b"}}; + json object_2 = {{"B", "b"}, {"A", "a"}}; + json number = 17; + json string = "foo"; + json discarded = json(json::value_t::discarded); + + // output values and comparisons + std::cout << array_1 << " <=> " << array_2 << " := " << to_string(array_1 <=> array_2) << '\n'; // *NOPAD* + std::cout << object_1 << " <=> " << object_2 << " := " << to_string(object_1 <=> object_2) << '\n'; // *NOPAD* + std::cout << string << " <=> " << number << " := " << to_string(string <=> number) << '\n'; // *NOPAD* + std::cout << string << " <=> " << discarded << " := " << to_string(string <=> discarded) << '\n'; // *NOPAD* +} +``` + +Output: + +``` +[1,2,3] <=> [1,2,4] := less +{"A":"a","B":"b"} <=> {"A":"a","B":"b"} := equivalent +"foo" <=> 17 := greater +"foo" <=> := unordered +``` + +Example: (2) comparing JSON values and scalars + +The example demonstrates comparing several JSON values and scalars. + +``` +#include +#include +#include + +using json = nlohmann::json; + +const char* to_string(const std::partial_ordering& po) +{ + if (std::is_lt(po)) + { + return "less"; + } + else if (std::is_gt(po)) + { + return "greater"; + } + else if (std::is_eq(po)) + { + return "equivalent"; + } + return "unordered"; +} + +int main() +{ + using float_limits = std::numeric_limits; + constexpr auto nan = float_limits::quiet_NaN(); + + // create several JSON values + json boolean = false; + json number = 17; + json string = "17"; + + // output values and comparisons + std::cout << std::boolalpha << std::fixed; + std::cout << boolean << " <=> " << true << " := " << to_string(boolean <=> true) << '\n'; // *NOPAD* + std::cout << number << " <=> " << 17.0 << " := " << to_string(number <=> 17.0) << '\n'; // *NOPAD* + std::cout << number << " <=> " << nan << " := " << to_string(number <=> nan) << '\n'; // *NOPAD* + std::cout << string << " <=> " << 17 << " := " << to_string(string <=> 17) << '\n'; // *NOPAD* +} +``` + +Output: + +``` +false <=> true := less +17 <=> 17.000000 := equivalent +17 <=> nan := unordered +"17" <=> 17 := greater +``` + +## See also + +- [**operator==**](https://json.nlohmann.me/api/basic_json/operator_eq/index.md) - comparison: equal +- [**operator!=**](https://json.nlohmann.me/api/basic_json/operator_ne/index.md) - comparison: not equal +- [**operator\<**](https://json.nlohmann.me/api/basic_json/operator_lt/index.md) - comparison: less than +- [**operator\<=**](https://json.nlohmann.me/api/basic_json/operator_le/index.md) - comparison: less than or equal +- [**operator>**](https://json.nlohmann.me/api/basic_json/operator_gt/index.md) - comparison: greater than +- [**operator>=**](https://json.nlohmann.me/api/basic_json/operator_ge/index.md) - comparison: greater than or equal + +## Version history + +1. Added in version 3.11.0. +1. Added in version 3.11.0. diff --git a/api/basic_json/operator_value_t.md b/api/basic_json/operator_value_t.md new file mode 100644 index 000000000..0f08f42b0 --- /dev/null +++ b/api/basic_json/operator_value_t.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::operator value_t + +```cpp +constexpr operator value_t() const noexcept; +``` + +Return the type of the JSON value as a value from the [`value_t`](value_t.md) enumeration. + +## Return value + +the type of the JSON value + +| Value type | return value | +|---------------------------|----------------------------| +| `#!json null` | `value_t::null` | +| boolean | `value_t::boolean` | +| string | `value_t::string` | +| number (integer) | `value_t::number_integer` | +| number (unsigned integer) | `value_t::number_unsigned` | +| number (floating-point) | `value_t::number_float` | +| object | `value_t::object` | +| array | `value_t::array` | +| binary | `value_t::binary` | +| discarded | `value_t::discarded` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `operator value_t()` for all JSON types. + + ```cpp + --8<-- "examples/operator__value_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator__value_t.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/api/basic_json/operator_value_t/index.html b/api/basic_json/operator_value_t/index.html index bc2054dae..6c32e6e52 100644 --- a/api/basic_json/operator_value_t/index.html +++ b/api/basic_json/operator_value_t/index.html @@ -45,4 +45,4 @@ true true true -

Version history

  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/operator_value_t/index.md b/api/basic_json/operator_value_t/index.md new file mode 100644 index 000000000..cbbcc4bf5 --- /dev/null +++ b/api/basic_json/operator_value_t/index.md @@ -0,0 +1,98 @@ +# nlohmann::basic_json::operator value_t + +``` +constexpr operator value_t() const noexcept; +``` + +Return the type of the JSON value as a value from the [`value_t`](https://json.nlohmann.me/api/basic_json/value_t/index.md) enumeration. + +## Return value + +the type of the JSON value + +| Value type | return value | +| ------------------------- | -------------------------- | +| `null` | `value_t::null` | +| boolean | `value_t::boolean` | +| string | `value_t::string` | +| number (integer) | `value_t::number_integer` | +| number (unsigned integer) | `value_t::number_unsigned` | +| number (floating-point) | `value_t::number_float` | +| object | `value_t::object` | +| array | `value_t::array` | +| binary | `value_t::binary` | +| discarded | `value_t::discarded` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `operator value_t()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = -17; + json j_number_unsigned = 42u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call operator value_t() + json::value_t t_null = j_null; + json::value_t t_boolean = j_boolean; + json::value_t t_number_integer = j_number_integer; + json::value_t t_number_unsigned = j_number_unsigned; + json::value_t t_number_float = j_number_float; + json::value_t t_object = j_object; + json::value_t t_array = j_array; + json::value_t t_string = j_string; + + // print types + std::cout << std::boolalpha; + std::cout << (t_null == json::value_t::null) << '\n'; + std::cout << (t_boolean == json::value_t::boolean) << '\n'; + std::cout << (t_number_integer == json::value_t::number_integer) << '\n'; + std::cout << (t_number_unsigned == json::value_t::number_unsigned) << '\n'; + std::cout << (t_number_float == json::value_t::number_float) << '\n'; + std::cout << (t_object == json::value_t::object) << '\n'; + std::cout << (t_array == json::value_t::array) << '\n'; + std::cout << (t_string == json::value_t::string) << '\n'; +} +``` + +Output: + +``` +true +true +true +true +true +true +true +true +``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/api/basic_json/other_error.md b/api/basic_json/other_error.md new file mode 100644 index 000000000..7019e75c5 --- /dev/null +++ b/api/basic_json/other_error.md @@ -0,0 +1,78 @@ +# nlohmann::basic_json::other_error + +```cpp +class other_error : public exception; +``` + +This exception is thrown in case of errors that cannot be classified with the other exception types. + +Exceptions have ids 5xx (see [list of other errors](../../home/exceptions.md#further-exceptions)). + +```mermaid +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_other_error fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `other_error` exception can be caught. + + ```cpp + --8<-- "examples/other_error.cpp" + ``` + + Output: + + ```json + --8<-- "examples/other_error.output" + ``` + +## See also + +- [`exception`](exception.md) for the base class of all exceptions thrown by the library +- [List of other errors](../../home/exceptions.md#further-exceptions) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/other_error/index.html b/api/basic_json/other_error/index.html index cc4c4dae4..b674cc85c 100644 --- a/api/basic_json/other_error/index.html +++ b/api/basic_json/other_error/index.html @@ -59,4 +59,4 @@ }

Output:

message: [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/best_biscuit/name","value":"Choco Leibniz"}
 exception id: 501
-

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file +

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/other_error/index.md b/api/basic_json/other_error/index.md new file mode 100644 index 000000000..bc4a3f2c0 --- /dev/null +++ b/api/basic_json/other_error/index.md @@ -0,0 +1,108 @@ +# nlohmann::basic_json::other_error + +``` +class other_error : public exception; +``` + +This exception is thrown in case of errors that cannot be classified with the other exception types. + +Exceptions have ids 5xx (see [list of other errors](https://json.nlohmann.me/home/exceptions/#further-exceptions)). + +``` +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_other_error fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +Example + +The following code shows how a `other_error` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + try + { + // executing a failing JSON Patch operation + json value = R"({ + "best_biscuit": { + "name": "Oreo" + } + })"_json; + json patch = R"([{ + "op": "test", + "path": "/best_biscuit/name", + "value": "Choco Leibniz" + }])"_json; + value.patch(patch); + } + catch (const json::other_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/best_biscuit/name","value":"Choco Leibniz"} +exception id: 501 +``` + +## See also + +- [`exception`](https://json.nlohmann.me/api/basic_json/exception/index.md) for the base class of all exceptions thrown by the library +- [List of other errors](https://json.nlohmann.me/home/exceptions/#further-exceptions) +- [`parse_error`](https://json.nlohmann.me/api/basic_json/parse_error/index.md) for exceptions indicating a parse error +- [`invalid_iterator`](https://json.nlohmann.me/api/basic_json/invalid_iterator/index.md) for exceptions indicating errors with iterators +- [`type_error`](https://json.nlohmann.me/api/basic_json/type_error/index.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](https://json.nlohmann.me/api/basic_json/out_of_range/index.md) for exceptions indicating access out of the defined range + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/out_of_range.md b/api/basic_json/out_of_range.md new file mode 100644 index 000000000..e1e54ae07 --- /dev/null +++ b/api/basic_json/out_of_range.md @@ -0,0 +1,79 @@ +# nlohmann::basic_json::out_of_range + +```cpp +class out_of_range : public exception; +``` + +This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for +instance, in the case of array indices or nonexisting object keys. + +Exceptions have ids 4xx (see [list of out-of-range errors](../../home/exceptions.md#out-of-range)). + +```mermaid +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_out_of_range fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `out_of_range` exception can be caught. + + ```cpp + --8<-- "examples/out_of_range.cpp" + ``` + + Output: + + ```json + --8<-- "examples/out_of_range.output" + ``` + +## See also + +- [`exception`](exception.md) for the base class of all exceptions thrown by the library +- [List of out-of-range errors](../../home/exceptions.md#out-of-range) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/out_of_range/index.html b/api/basic_json/out_of_range/index.html index 22f18adc2..a4af85589 100644 --- a/api/basic_json/out_of_range/index.html +++ b/api/basic_json/out_of_range/index.html @@ -49,4 +49,4 @@ }

Output:

message: [json.exception.out_of_range.401] array index 4 is out of range
 exception id: 401
-

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file +

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/out_of_range/index.md b/api/basic_json/out_of_range/index.md new file mode 100644 index 000000000..ab4ab4acc --- /dev/null +++ b/api/basic_json/out_of_range/index.md @@ -0,0 +1,98 @@ +# nlohmann::basic_json::out_of_range + +``` +class out_of_range : public exception; +``` + +This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys. + +Exceptions have ids 4xx (see [list of out-of-range errors](https://json.nlohmann.me/home/exceptions/#out-of-range)). + +``` +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_out_of_range fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +Example + +The following code shows how a `out_of_range` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling at() for an invalid index + json j = {1, 2, 3, 4}; + j.at(4) = 10; + } + catch (const json::out_of_range& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.out_of_range.401] array index 4 is out of range +exception id: 401 +``` + +## See also + +- [`exception`](https://json.nlohmann.me/api/basic_json/exception/index.md) for the base class of all exceptions thrown by the library +- [List of out-of-range errors](https://json.nlohmann.me/home/exceptions/#out-of-range) +- [`parse_error`](https://json.nlohmann.me/api/basic_json/parse_error/index.md) for exceptions indicating a parse error +- [`invalid_iterator`](https://json.nlohmann.me/api/basic_json/invalid_iterator/index.md) for exceptions indicating errors with iterators +- [`type_error`](https://json.nlohmann.me/api/basic_json/type_error/index.md) for exceptions indicating executing a member function with a wrong type +- [`other_error`](https://json.nlohmann.me/api/basic_json/other_error/index.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/parse.md b/api/basic_json/parse.md new file mode 100644 index 000000000..4da93ae42 --- /dev/null +++ b/api/basic_json/parse.md @@ -0,0 +1,247 @@ +# nlohmann::basic_json::parse + +```cpp +// (1) +template +static basic_json parse(InputType&& i, + const parser_callback_t cb = nullptr, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); + +// (2) +template +static basic_json parse(IteratorType first, IteratorType last, + const parser_callback_t cb = nullptr, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +1. Deserialize from a compatible input. +2. Deserialize from a pair of character iterators + + The `value_type` of the iterator must be an integral type with size of 1, 2, or 4 bytes, which will be interpreted + respectively as UTF-8, UTF-16, and UTF-32. + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer (throws if null) + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters (throws if null) + - a `std::string` + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. + +`IteratorType` +: a compatible iterator type, for instance. + + - a pair of `std::string::iterator` or `std::vector::iterator` + - a pair of pointers such as `ptr` and `ptr + len` + +## Parameters + +`i` (in) +: Input to parse from. + +`cb` (in) +: a parser callback function of type [`parser_callback_t`](parser_callback_t.md) which is used to control the + deserialization by filtering unwanted values (optional) + +`allow_exceptions` (in) +: whether to throw exceptions in case of a parse error (optional, `#!cpp true` by default) + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`ignore_trailing_commas` (in) +: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`first` (in) +: iterator to the start of a character range + +`last` (in) +: iterator to the end of a character range + +## Return value + +Deserialized JSON value; in case of a parse error and `allow_exceptions` set to `#!cpp false`, the return value will be +`value_t::discarded`. The latter can be checked with [`is_discarded`](is_discarded.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token, or + empty input like a null `FILE*` or `char*` pointer. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser +callback function `cb` or reading from (1) the input `i` or (2) the iterator range [`first`, `last`] has a +super-linear complexity. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +Invalid Unicode escapes and unpaired surrogates in the input are reported as +[`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) with a detailed message. + +## Examples + +??? example "Parsing from a character array" + + The example below demonstrates the `parse()` function reading from an array. + + ```cpp + --8<-- "examples/parse__array__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__array__parser_callback_t.output" + ``` + +??? example "Parsing from a string" + + The example below demonstrates the `parse()` function with and without callback function. + + ```cpp + --8<-- "examples/parse__string__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__string__parser_callback_t.output" + ``` + +??? example "Parsing from an input stream" + + The example below demonstrates the `parse()` function with and without callback function. + + ```cpp + --8<-- "examples/parse__istream__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__istream__parser_callback_t.output" + ``` + +??? example "Parsing from a contiguous container" + + The example below demonstrates the `parse()` function reading from a contiguous container. + + ```cpp + --8<-- "examples/parse__contiguouscontainer__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__contiguouscontainer__parser_callback_t.output" + ``` + +??? example "Parsing from a non-null-terminated string" + + The example below demonstrates the `parse()` function reading from a string that is not null-terminated. + + ```cpp + --8<-- "examples/parse__pointers.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__pointers.output" + ``` + +??? example "Parsing from an iterator pair" + + The example below demonstrates the `parse()` function reading from an iterator pair. + + ```cpp + --8<-- "examples/parse__iterator_pair.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__iterator_pair.output" + ``` + +??? example "Effect of `allow_exceptions` parameter" + + The example below demonstrates the effect of the `allow_exceptions` parameter in the `parse()` function. + + ```cpp + --8<-- "examples/parse__allow_exceptions.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__allow_exceptions.output" + ``` + +??? example "Effect of `ignore_comments` parameter" + + The example below demonstrates the effect of the `ignore_comments` parameter in the `parse()` function. + + ```cpp + --8<-- "examples/comments.cpp" + ``` + + Output: + + ``` + --8<-- "examples/comments.output" + ``` + +??? example "Effect of `ignore_trailing_commas` parameter" + + The example below demonstrates the effect of the `ignore_trailing_commas` parameter in the `parse()` function. + + ```cpp + --8<-- "examples/trailing_commas.cpp" + ``` + + Output: + + ``` + --8<-- "examples/trailing_commas.output" + ``` + +## See also + +- [accept](accept.md) - check if the input is valid JSON +- [sax_parse](sax_parse.md) - parse input using the SAX interface +- [operator>>](../operator_gtgt.md) - deserialize from stream + +## Version history + +- Added in version 1.0.0. +- Overload for contiguous containers (1) added in version 2.0.3. +- Ignoring comments via `ignore_comments` added in version 3.9.0. +- Changed [runtime assertion](../../features/assertions.md) in case of `FILE*` null pointers to exception in version 3.12.0. +- Added `ignore_trailing_commas` in version 3.12.x. + +!!! warning "Deprecation" + + Overload (2) replaces calls to `parse` with a pair of iterators as their first parameter which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp parse({ptr, ptr+len}, ...);` with `#!cpp parse(ptr, ptr+len, ...);`. + + You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated + function. diff --git a/api/basic_json/parse/index.html b/api/basic_json/parse/index.html index 21fc1a9a8..b3cbb2b7f 100644 --- a/api/basic_json/parse/index.html +++ b/api/basic_json/parse/index.html @@ -424,4 +424,4 @@ "Neptune" ] } -

See also

  • accept - check if the input is valid JSON
  • sax_parse - parse input using the SAX interface
  • operator>> - deserialize from stream

Version history

  • Added in version 1.0.0.
  • Overload for contiguous containers (1) added in version 2.0.3.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • Added ignore_trailing_commas in version 3.12.x.

Deprecation

Overload (2) replaces calls to parse with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like parse({ptr, ptr+len}, ...); with parse(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file +

See also

  • accept - check if the input is valid JSON
  • sax_parse - parse input using the SAX interface
  • operator>> - deserialize from stream

Version history

  • Added in version 1.0.0.
  • Overload for contiguous containers (1) added in version 2.0.3.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Changed runtime assertion in case of FILE* null pointers to exception in version 3.12.0.
  • Added ignore_trailing_commas in version 3.12.x.

Deprecation

Overload (2) replaces calls to parse with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like parse({ptr, ptr+len}, ...); with parse(ptr, ptr+len, ...);.

You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.

\ No newline at end of file diff --git a/api/basic_json/parse/index.md b/api/basic_json/parse/index.md new file mode 100644 index 000000000..5c7db327c --- /dev/null +++ b/api/basic_json/parse/index.md @@ -0,0 +1,624 @@ +# nlohmann::basic_json::parse + +``` +// (1) +template +static basic_json parse(InputType&& i, + const parser_callback_t cb = nullptr, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); + +// (2) +template +static basic_json parse(IteratorType first, IteratorType last, + const parser_callback_t cb = nullptr, + const bool allow_exceptions = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +1. Deserialize from a compatible input. + +1. Deserialize from a pair of character iterators + + The `value_type` of the iterator must be an integral type with size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer (throws if null) +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters (throws if null) +- a `std::string` +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of iterators. +``` + +`IteratorType` : a compatible iterator type, for instance. + +``` +- a pair of `std::string::iterator` or `std::vector::iterator` +- a pair of pointers such as `ptr` and `ptr + len` +``` + +## Parameters + +`i` (in) : Input to parse from. + +`cb` (in) : a parser callback function of type [`parser_callback_t`](https://json.nlohmann.me/api/basic_json/parser_callback_t/index.md) which is used to control the deserialization by filtering unwanted values (optional) + +`allow_exceptions` (in) : whether to throw exceptions in case of a parse error (optional, `true` by default) + +`ignore_comments` (in) : whether comments should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default) + +`ignore_trailing_commas` (in) : whether trailing commas in arrays or objects should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default) + +`first` (in) : iterator to the start of a character range + +`last` (in) : iterator to the end of a character range + +## Return value + +Deserialized JSON value; in case of a parse error and `allow_exceptions` set to `false`, the return value will be `value_t::discarded`. The latter can be checked with [`is_discarded`](https://json.nlohmann.me/api/basic_json/is_discarded/index.md). + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.101`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error101) in case of an unexpected token, or empty input like a null `FILE*` or `char*` pointer. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser callback function `cb` or reading from (1) the input `i` or (2) the iterator range \[`first`, `last`\] has a super-linear complexity. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +Invalid Unicode escapes and unpaired surrogates in the input are reported as [`parse_error.101`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error101) with a detailed message. + +## Examples + +Parsing from a character array + +The example below demonstrates the `parse()` function reading from an array. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + char text[] = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; +} +``` + +Output: + +``` +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} +``` + +Parsing from a string + +The example below demonstrates the `parse()` function with and without callback function. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; + + // define parser callback + json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed) + { + // skip object elements with key "Thumbnail" + if (event == json::parse_event_t::key and parsed == json("Thumbnail")) + { + return false; + } + else + { + return true; + } + }; + + // parse (with callback) and serialize JSON + json j_filtered = json::parse(text, cb); + std::cout << std::setw(4) << j_filtered << '\n'; +} +``` + +Output: + +``` +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Title": "View from 15th Floor", + "Width": 800 + } +} +``` + +Parsing from an input stream + +The example below demonstrates the `parse()` function with and without callback function. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // fill a stream with JSON text + std::stringstream ss; + ss << text; + + // parse and serialize JSON + json j_complete = json::parse(ss); + std::cout << std::setw(4) << j_complete << "\n\n"; + + // define parser callback + json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed) + { + // skip object elements with key "Thumbnail" + if (event == json::parse_event_t::key and parsed == json("Thumbnail")) + { + return false; + } + else + { + return true; + } + }; + + // fill a stream with JSON text + ss.clear(); + ss << text; + + // parse (with callback) and serialize JSON + json j_filtered = json::parse(ss, cb); + std::cout << std::setw(4) << j_filtered << '\n'; +} +``` + +Output: + +``` +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Title": "View from 15th Floor", + "Width": 800 + } +} +``` + +Parsing from a contiguous container + +The example below demonstrates the `parse()` function reading from a contiguous container. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given as std::vector + std::vector text = {'[', '1', ',', '2', ',', '3', ']', '\0'}; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; +} +``` + +Output: + +``` +[ + 1, + 2, + 3 +] +``` + +Parsing from a non-null-terminated string + +The example below demonstrates the `parse()` function reading from a string that is not null-terminated. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given as string that is not null-terminated + const char* ptr = "[1,2,3]another value"; + + // parse and serialize JSON + json j_complete = json::parse(ptr, ptr + 7); + std::cout << std::setw(4) << j_complete << "\n\n"; +} +``` + +Output: + +``` +[ + 1, + 2, + 3 +] +``` + +Parsing from an iterator pair + +The example below demonstrates the `parse()` function reading from an iterator pair. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text given an input with other values + std::vector input = {'[', '1', ',', '2', ',', '3', ']', 'o', 't', 'h', 'e', 'r'}; + + // parse and serialize JSON + json j_complete = json::parse(input.begin(), input.begin() + 7); + std::cout << std::setw(4) << j_complete << "\n\n"; +} +``` + +Output: + +``` +[ + 1, + 2, + 3 +] +``` + +Effect of `allow_exceptions` parameter + +The example below demonstrates the effect of the `allow_exceptions` parameter in the `parse()` function. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // an invalid JSON text + std::string text = R"( + { + "key": "value without closing quotes + } + )"; + + // parse with exceptions + try + { + json j = json::parse(text); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << std::endl; + } + + // parse without exceptions + json j = json::parse(text, nullptr, false); + + if (j.is_discarded()) + { + std::cout << "the input is invalid JSON" << std::endl; + } + else + { + std::cout << "the input is valid JSON: " << j << std::endl; + } +} +``` + +Output: + +``` +[json.exception.parse_error.101] parse error at line 4, column 0: syntax error while parsing value - invalid string: control character U+000A (LF) must be escaped to \u000A or \n; last read: '"value without closing quotes' +the input is invalid JSON +``` + +Effect of `ignore_comments` parameter + +The example below demonstrates the effect of the `ignore_comments` parameter in the `parse()` function. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::string s = R"( + { + // update in 2006: removed Pluto + "planets": ["Mercury", "Venus", "Earth", "Mars", + "Jupiter", "Uranus", "Neptune" /*, "Pluto" */] + } + )"; + + try + { + json j = json::parse(s); + } + catch (json::exception& e) + { + std::cout << e.what() << std::endl; + } + + json j = json::parse(s, + /* callback */ nullptr, + /* allow exceptions */ true, + /* ignore_comments */ true); + std::cout << j.dump(2) << '\n'; +} +``` + +Output: + +``` +[json.exception.parse_error.101] parse error at line 3, column 9: syntax error while parsing object key - invalid literal; last read: ' { /'; expected string literal +{ + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune" + ] +} +``` + +Effect of `ignore_trailing_commas` parameter + +The example below demonstrates the effect of the `ignore_trailing_commas` parameter in the `parse()` function. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::string s = R"( + { + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune", + ] + } + )"; + + try + { + json j = json::parse(s); + } + catch (json::exception& e) + { + std::cout << e.what() << std::endl; + } + + json j = json::parse(s, + /* callback */ nullptr, + /* allow exceptions */ true, + /* ignore_comments */ false, + /* ignore_trailing_commas */ true); + std::cout << j.dump(2) << '\n'; +} +``` + +Output: + +``` +[json.exception.parse_error.101] parse error at line 11, column 9: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal +{ + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune" + ] +} +``` + +## See also + +- [accept](https://json.nlohmann.me/api/basic_json/accept/index.md) - check if the input is valid JSON +- [sax_parse](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) - parse input using the SAX interface +- [operator>>](https://json.nlohmann.me/api/operator_gtgt/index.md) - deserialize from stream + +## Version history + +- Added in version 1.0.0. +- Overload for contiguous containers (1) added in version 2.0.3. +- Ignoring comments via `ignore_comments` added in version 3.9.0. +- Changed [runtime assertion](https://json.nlohmann.me/features/assertions/index.md) in case of `FILE*` null pointers to exception in version 3.12.0. +- Added `ignore_trailing_commas` in version 3.12.x. + +Deprecation + +Overload (2) replaces calls to `parse` with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `parse({ptr, ptr+len}, ...);` with `parse(ptr, ptr+len, ...);`. + +You should be warned by your compiler with a `-Wdeprecated-declarations` warning if you are using a deprecated function. diff --git a/api/basic_json/parse_error.md b/api/basic_json/parse_error.md new file mode 100644 index 000000000..9931d5463 --- /dev/null +++ b/api/basic_json/parse_error.md @@ -0,0 +1,87 @@ +# nlohmann::basic_json::parse_error + +```cpp +class parse_error : public exception; +``` + +The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of +JSON text, BSON, CBOR, MessagePack, UBJSON, as well as when using JSON Patch. + +Member `byte` holds the byte index of the last read character in the input file (see note below). + +Exceptions have ids 1xx (see [list of parse errors](../../home/exceptions.md#parse-errors)). + +```mermaid +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_parse_error fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception +- **byte** - byte index of the parse error + +## Notes + +For an input with $n$ bytes, 1 is the index of the first character and $n+1$ is the index of the terminating null byte +or the end of file. This also holds true when reading a byte vector for binary formats. + +## Examples + +??? example + + The following code shows how a `parse_error` exception can be caught. + + ```cpp + --8<-- "examples/parse_error.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse_error.output" + ``` + +## See also + +- [`exception`](exception.md) for the base class of all exceptions thrown by the library +- [List of parse errors](../../home/exceptions.md#parse-errors) +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/parse_error/index.html b/api/basic_json/parse_error/index.html index cf6d7cd7c..cfcd83108 100644 --- a/api/basic_json/parse_error/index.html +++ b/api/basic_json/parse_error/index.html @@ -50,4 +50,4 @@

Output:

message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal
 exception id: 101
 byte position of error: 8
-

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file +

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/parse_error/index.md b/api/basic_json/parse_error/index.md new file mode 100644 index 000000000..edc14ae11 --- /dev/null +++ b/api/basic_json/parse_error/index.md @@ -0,0 +1,106 @@ +# nlohmann::basic_json::parse_error + +``` +class parse_error : public exception; +``` + +The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text, BSON, CBOR, MessagePack, UBJSON, as well as when using JSON Patch. + +Member `byte` holds the byte index of the last read character in the input file (see note below). + +Exceptions have ids 1xx (see [list of parse errors](https://json.nlohmann.me/home/exceptions/#parse-errors)). + +``` +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_parse_error fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception +- **byte** - byte index of the parse error + +## Notes + +For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector for binary formats. + +## Examples + +Example + +The following code shows how a `parse_error` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // parsing input with a syntax error + json::parse("[1,2,3,]"); + } + catch (const json::parse_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << '\n' + << "byte position of error: " << e.byte << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal +exception id: 101 +byte position of error: 8 +``` + +## See also + +- [`exception`](https://json.nlohmann.me/api/basic_json/exception/index.md) for the base class of all exceptions thrown by the library +- [List of parse errors](https://json.nlohmann.me/home/exceptions/#parse-errors) +- [`invalid_iterator`](https://json.nlohmann.me/api/basic_json/invalid_iterator/index.md) for exceptions indicating errors with iterators +- [`type_error`](https://json.nlohmann.me/api/basic_json/type_error/index.md) for exceptions indicating executing a member function with a wrong type +- [`out_of_range`](https://json.nlohmann.me/api/basic_json/out_of_range/index.md) for exceptions indicating access out of the defined range +- [`other_error`](https://json.nlohmann.me/api/basic_json/other_error/index.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/parse_event_t.md b/api/basic_json/parse_event_t.md new file mode 100644 index 000000000..36cba925f --- /dev/null +++ b/api/basic_json/parse_event_t.md @@ -0,0 +1,34 @@ +# nlohmann::basic_json::parse_event_t + +```cpp +enum class parse_event_t : std::uint8_t { + object_start, + object_end, + array_start, + array_end, + key, + value +}; +``` + +The parser callback distinguishes the following events: + +- `object_start`: the parser read `{` and started to process a JSON object +- `key`: the parser read a key of a value in an object +- `object_end`: the parser read `}` and finished processing a JSON object +- `array_start`: the parser read `[` and started to process a JSON array +- `array_end`: the parser read `]` and finished processing a JSON array +- `value`: the parser finished reading a JSON value + +## Examples + +![Example when certain parse events are triggered](../../images/callback_events.png) + +## See also + +- [parser_callback_t](parser_callback_t.md) callback function type for the parser +- [parse](parse.md) deserialize from a compatible input + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/parse_event_t/index.html b/api/basic_json/parse_event_t/index.html index 39dd39fb4..1b6610426 100644 --- a/api/basic_json/parse_event_t/index.html +++ b/api/basic_json/parse_event_t/index.html @@ -6,4 +6,4 @@ key, value }; -

The parser callback distinguishes the following events:

  • object_start: the parser read { and started to process a JSON object
  • key: the parser read a key of a value in an object
  • object_end: the parser read } and finished processing a JSON object
  • array_start: the parser read [ and started to process a JSON array
  • array_end: the parser read ] and finished processing a JSON array
  • value: the parser finished reading a JSON value

Examples

Example when certain parse events are triggered

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

The parser callback distinguishes the following events:

  • object_start: the parser read { and started to process a JSON object
  • key: the parser read a key of a value in an object
  • object_end: the parser read } and finished processing a JSON object
  • array_start: the parser read [ and started to process a JSON array
  • array_end: the parser read ] and finished processing a JSON array
  • value: the parser finished reading a JSON value

Examples

Example when certain parse events are triggered

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/parse_event_t/index.md b/api/basic_json/parse_event_t/index.md new file mode 100644 index 000000000..4cb7f295b --- /dev/null +++ b/api/basic_json/parse_event_t/index.md @@ -0,0 +1,32 @@ +# nlohmann::basic_json::parse_event_t + +``` +enum class parse_event_t : std::uint8_t { + object_start, + object_end, + array_start, + array_end, + key, + value +}; +``` + +The parser callback distinguishes the following events: + +- `object_start`: the parser read `{` and started to process a JSON object +- `key`: the parser read a key of a value in an object +- `object_end`: the parser read `}` and finished processing a JSON object +- `array_start`: the parser read `[` and started to process a JSON array +- `array_end`: the parser read `]` and finished processing a JSON array +- `value`: the parser finished reading a JSON value + +## Examples + +## See also + +- [parser_callback_t](https://json.nlohmann.me/api/basic_json/parser_callback_t/index.md) callback function type for the parser +- [parse](https://json.nlohmann.me/api/basic_json/parse/index.md) deserialize from a compatible input + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/parser_callback_t.md b/api/basic_json/parser_callback_t.md new file mode 100644 index 000000000..460f69cbb --- /dev/null +++ b/api/basic_json/parser_callback_t.md @@ -0,0 +1,78 @@ +# nlohmann::basic_json::parser_callback_t + +```cpp +template +using parser_callback_t = + std::function; +``` + +With a parser callback function, the result of parsing a JSON text can be influenced. When passed to +[`parse`](parse.md), it is called on certain events (passed as [`parse_event_t`](parse_event_t.md) via parameter +`event`) with a set recursion depth `depth` and context JSON value `parsed`. The return value of the callback function +is a boolean indicating whether the element that emitted the callback shall be kept or not. + +We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following +table describes the values of the parameters `depth`, `event`, and `parsed`. + +| parameter `event` | description | parameter `depth` | parameter `parsed` | +|-------------------------------|-----------------------------------------------------------|-------------------------------------------|----------------------------------| +| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded | +| `parse_event_t::key` | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key | +| `parse_event_t::object_end` | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object | +| `parse_event_t::array_start` | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded | +| `parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array | +| `parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value | + +![Example when certain parse events are triggered](../../images/callback_events.png) + +Discarding a value (i.e., returning `#!cpp false`) has different effects depending on the context in which function was +called: + +- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never + read. +- In case a value outside a structured type is skipped, it is replaced with `null`. This case happens if the top-level + element is skipped. + +## Parameters + +`depth` (in) +: the depth of the recursion during parsing + +`event` (in) +: an event of type [`parse_event_t`](parse_event_t.md) indicating the context in + the callback function has been called + +`parsed` (in, out) +: the current intermediate parse result; note that + writing to this value has no effect for `parse_event_t::key` events + +## Return value + +Whether the JSON value which called the function during parsing should be kept (`#!cpp true`) or not (`#!cpp false`). In +the latter case, it is either skipped completely or replaced by an empty discarded object. + +## Examples + +??? example + + The example below demonstrates the `parse()` function with + and without callback function. + + ```cpp + --8<-- "examples/parse__string__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__string__parser_callback_t.output" + ``` + +## See also + +- [parse](parse.md) deserialize from a compatible input +- [parse_event_t](parse_event_t.md) enumeration of parser events + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/parser_callback_t/index.html b/api/basic_json/parser_callback_t/index.html index 15272aeeb..2ac9b7353 100644 --- a/api/basic_json/parser_callback_t/index.html +++ b/api/basic_json/parser_callback_t/index.html @@ -83,4 +83,4 @@ "Width": 800 } } -

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/parser_callback_t/index.md b/api/basic_json/parser_callback_t/index.md new file mode 100644 index 000000000..16a4e2591 --- /dev/null +++ b/api/basic_json/parser_callback_t/index.md @@ -0,0 +1,142 @@ +# nlohmann::basic_json::parser_callback_t + +``` +template +using parser_callback_t = + std::function; +``` + +With a parser callback function, the result of parsing a JSON text can be influenced. When passed to [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md), it is called on certain events (passed as [`parse_event_t`](https://json.nlohmann.me/api/basic_json/parse_event_t/index.md) via parameter `event`) with a set recursion depth `depth` and context JSON value `parsed`. The return value of the callback function is a boolean indicating whether the element that emitted the callback shall be kept or not. + +We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values of the parameters `depth`, `event`, and `parsed`. + +| parameter `event` | description | parameter `depth` | parameter `parsed` | +| ----------------------------- | --------------------------------------------------------- | ----------------------------------------- | -------------------------------- | +| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded | +| `parse_event_t::key` | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key | +| `parse_event_t::object_end` | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object | +| `parse_event_t::array_start` | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded | +| `parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array | +| `parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value | + +Discarding a value (i.e., returning `false`) has different effects depending on the context in which function was called: + +- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read. +- In case a value outside a structured type is skipped, it is replaced with `null`. This case happens if the top-level element is skipped. + +## Parameters + +`depth` (in) : the depth of the recursion during parsing + +`event` (in) : an event of type [`parse_event_t`](https://json.nlohmann.me/api/basic_json/parse_event_t/index.md) indicating the context in the callback function has been called + +`parsed` (in, out) : the current intermediate parse result; note that writing to this value has no effect for `parse_event_t::key` events + +## Return value + +Whether the JSON value which called the function during parsing should be kept (`true`) or not (`false`). In the latter case, it is either skipped completely or replaced by an empty discarded object. + +## Examples + +Example + +The example below demonstrates the `parse()` function with and without callback function. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; + + // define parser callback + json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed) + { + // skip object elements with key "Thumbnail" + if (event == json::parse_event_t::key and parsed == json("Thumbnail")) + { + return false; + } + else + { + return true; + } + }; + + // parse (with callback) and serialize JSON + json j_filtered = json::parse(text, cb); + std::cout << std::setw(4) << j_filtered << '\n'; +} +``` + +Output: + +``` +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Title": "View from 15th Floor", + "Width": 800 + } +} +``` + +## See also + +- [parse](https://json.nlohmann.me/api/basic_json/parse/index.md) deserialize from a compatible input +- [parse_event_t](https://json.nlohmann.me/api/basic_json/parse_event_t/index.md) enumeration of parser events + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/patch.md b/api/basic_json/patch.md new file mode 100644 index 000000000..1ec517461 --- /dev/null +++ b/api/basic_json/patch.md @@ -0,0 +1,77 @@ +# nlohmann::basic_json::patch + +```cpp +basic_json patch(const basic_json& json_patch) const; +``` + +[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to +a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from +the patch. + +## Parameters + +`json_patch` (in) +: JSON patch document + +## Return value + +patched document + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of + an array of objects. +- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g., + mandatory attributes are missing); example: `"operation add must have member path"`. +- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range. +- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch + could not be resolved successfully in the current JSON value; example: `"key baz not found"`. +- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent + ("add", "remove", "move") +- Throws [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) if an "add" operation's target + location has a parent that is neither an object nor an array. +- Throws [`other_error.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was + unsuccessful. + +## Complexity + +Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of +the JSON value, the complexity can usually be neglected. + +## Notes + +The application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception +is thrown. In any case, the original value is not changed: the patch is applied to a copy of the value. + +## Examples + +??? example + + The following code shows how a JSON patch is applied to a value. + + ```cpp + --8<-- "examples/patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/patch.output" + ``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) +- [patch_inplace](patch_inplace.md) applies a JSON Patch without creating a copy of the document +- [merge_patch](merge_patch.md) applies a JSON Merge Patch + +## Version history + +- Added in version 2.0.0. +- Added [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's + target location has a non-object/non-array parent in version 3.12.x. diff --git a/api/basic_json/patch/index.html b/api/basic_json/patch/index.html index 706970a7b..bf977bbf3 100644 --- a/api/basic_json/patch/index.html +++ b/api/basic_json/patch/index.html @@ -43,4 +43,4 @@ "world" ] } -

See also

Version history

  • Added in version 2.0.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.12.x.
\ No newline at end of file +

See also

Version history

  • Added in version 2.0.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.12.x.
\ No newline at end of file diff --git a/api/basic_json/patch/index.md b/api/basic_json/patch/index.md new file mode 100644 index 000000000..6343c836c --- /dev/null +++ b/api/basic_json/patch/index.md @@ -0,0 +1,107 @@ +# nlohmann::basic_json::patch + +``` +basic_json patch(const basic_json& json_patch) const; +``` + +[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. + +## Parameters + +`json_patch` (in) : JSON patch document + +## Return value + +patched document + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.104`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error104) if the JSON patch does not consist of an array of objects. +- Throws [`parse_error.105`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error105) if the JSON patch is malformed (e.g., mandatory attributes are missing); example: `"operation add must have member path"`. +- Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if an array index is out of range. +- Throws [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403) if a JSON pointer inside the patch could not be resolved successfully in the current JSON value; example: `"key baz not found"`. +- Throws [`out_of_range.405`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range405) if JSON pointer has no parent ("add", "remove", "move") +- Throws [`out_of_range.411`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range411) if an "add" operation's target location has a parent that is neither an object nor an array. +- Throws [`other_error.501`](https://json.nlohmann.me/home/exceptions/#jsonexceptionother_error501) if "test" operation was unsuccessful. + +## Complexity + +Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected. + +## Notes + +The application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception is thrown. In any case, the original value is not changed: the patch is applied to a copy of the value. + +## Examples + +Example + +The following code shows how a JSON patch is applied to a value. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json doc = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the patch + json patch = R"( + [ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} + ] + )"_json; + + // apply the patch + json patched_doc = doc.patch(patch); + + // output original and patched document + std::cout << std::setw(4) << doc << "\n\n" + << std::setw(4) << patched_doc << std::endl; +} +``` + +Output: + +``` +{ + "baz": "qux", + "foo": "bar" +} + +{ + "baz": "boo", + "hello": [ + "world" + ] +} +``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) +- [patch_inplace](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md) applies a JSON Patch without creating a copy of the document +- [merge_patch](https://json.nlohmann.me/api/basic_json/merge_patch/index.md) applies a JSON Merge Patch + +## Version history + +- Added in version 2.0.0. +- Added [`out_of_range.411`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.12.x. diff --git a/api/basic_json/patch_inplace.md b/api/basic_json/patch_inplace.md new file mode 100644 index 000000000..8f88c612f --- /dev/null +++ b/api/basic_json/patch_inplace.md @@ -0,0 +1,74 @@ +# nlohmann::basic_json::patch_inplace + +```cpp +void patch_inplace(const basic_json& json_patch); +``` + +[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to +a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from +the patch. This function applies a JSON patch in place and returns void. + +## Parameters + +`json_patch` (in) +: JSON patch document + +## Exception safety + +No guarantees, value may be corrupted by an unsuccessful patch operation. + +## Exceptions + +- Throws [`parse_error.104`](../../home/exceptions.md#jsonexceptionparse_error104) if the JSON patch does not consist of + an array of objects. +- Throws [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105) if the JSON patch is malformed (e.g., + mandatory attributes are missing); example: `"operation add must have member path"`. +- Throws [`out_of_range.401`](../../home/exceptions.md#jsonexceptionout_of_range401) if an array index is out of range. +- Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch + could not be resolved successfully in the current JSON value; example: `"key baz not found"`. +- Throws [`out_of_range.405`](../../home/exceptions.md#jsonexceptionout_of_range405) if JSON pointer has no parent + ("add", "remove", "move") +- Throws [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) if an "add" operation's target + location has a parent that is neither an object nor an array. +- Throws [`other_error.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was + unsuccessful. + +## Complexity + +Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of +the JSON value, the complexity can usually be neglected. + +## Notes + +Unlike [`patch`](patch.md), `patch_inplace` applies the operation "in place" and no copy of the JSON value is created. +That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the +function throws an exception. + +## Examples + +??? example + + The following code shows how a JSON patch is applied to a value. + + ```cpp + --8<-- "examples/patch_inplace.cpp" + ``` + + Output: + + ```json + --8<-- "examples/patch_inplace.output" + ``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) +- [patch](patch.md) applies a JSON Patch +- [merge_patch](merge_patch.md) applies a JSON Merge Patch + +## Version history + +- Added in version 3.11.0. +- Added [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's + target location has a non-object/non-array parent in version 3.12.x. diff --git a/api/basic_json/patch_inplace/index.html b/api/basic_json/patch_inplace/index.html index 301bb9c6f..bfa2e2873 100644 --- a/api/basic_json/patch_inplace/index.html +++ b/api/basic_json/patch_inplace/index.html @@ -47,4 +47,4 @@ "world" ] } -

See also

Version history

  • Added in version 3.11.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.12.x.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.0.
  • Added out_of_range.411 and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.12.x.
\ No newline at end of file diff --git a/api/basic_json/patch_inplace/index.md b/api/basic_json/patch_inplace/index.md new file mode 100644 index 000000000..a38509cc1 --- /dev/null +++ b/api/basic_json/patch_inplace/index.md @@ -0,0 +1,107 @@ +# nlohmann::basic_json::patch_inplace + +``` +void patch_inplace(const basic_json& json_patch); +``` + +[JSON Patch](http://jsonpatch.com) defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. This function applies a JSON patch in place and returns void. + +## Parameters + +`json_patch` (in) : JSON patch document + +## Exception safety + +No guarantees, value may be corrupted by an unsuccessful patch operation. + +## Exceptions + +- Throws [`parse_error.104`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error104) if the JSON patch does not consist of an array of objects. +- Throws [`parse_error.105`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error105) if the JSON patch is malformed (e.g., mandatory attributes are missing); example: `"operation add must have member path"`. +- Throws [`out_of_range.401`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range401) if an array index is out of range. +- Throws [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403) if a JSON pointer inside the patch could not be resolved successfully in the current JSON value; example: `"key baz not found"`. +- Throws [`out_of_range.405`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range405) if JSON pointer has no parent ("add", "remove", "move") +- Throws [`out_of_range.411`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range411) if an "add" operation's target location has a parent that is neither an object nor an array. +- Throws [`other_error.501`](https://json.nlohmann.me/home/exceptions/#jsonexceptionother_error501) if "test" operation was unsuccessful. + +## Complexity + +Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected. + +## Notes + +Unlike [`patch`](https://json.nlohmann.me/api/basic_json/patch/index.md), `patch_inplace` applies the operation "in place" and no copy of the JSON value is created. That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the function throws an exception. + +## Examples + +Example + +The following code shows how a JSON patch is applied to a value. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json doc = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the patch + json patch = R"( + [ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} + ] + )"_json; + + // output original document + std::cout << "Before\n" << std::setw(4) << doc << std::endl; + + // apply the patch + doc.patch_inplace(patch); + + // output patched document + std::cout << "\nAfter\n" << std::setw(4) << doc << std::endl; +} +``` + +Output: + +``` +Before +{ + "baz": "qux", + "foo": "bar" +} + +After +{ + "baz": "boo", + "hello": [ + "world" + ] +} +``` + +## See also + +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) +- [patch](https://json.nlohmann.me/api/basic_json/patch/index.md) applies a JSON Patch +- [merge_patch](https://json.nlohmann.me/api/basic_json/merge_patch/index.md) applies a JSON Merge Patch + +## Version history + +- Added in version 3.11.0. +- Added [`out_of_range.411`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.12.x. diff --git a/api/basic_json/push_back.md b/api/basic_json/push_back.md new file mode 100644 index 000000000..9d518e79e --- /dev/null +++ b/api/basic_json/push_back.md @@ -0,0 +1,124 @@ +# nlohmann::basic_json::push_back + +```cpp +// (1) +void push_back(basic_json&& val); +void push_back(const basic_json& val); + +// (2) +void push_back(const typename object_t::value_type& val); + +// (3) +void push_back(initializer_list_t init); +``` + +1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an + empty array is created before appending `val`. + +2. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object + is created before inserting `val`. + +3. This function allows using `push_back` with an initializer list. In case + + 1. the current value is an object, + 2. the initializer list `init` contains only two elements, and + 3. the first element of `init` is a string, + + `init` is converted into an object element and added using `push_back(const typename object_t::value_type&)`. + Otherwise, `init` is converted to a JSON value and added using `push_back(basic_json&&)`. + +## Iterator invalidation + +For all cases where an element is added to an **array**, a reallocation can happen, in which case all iterators (including +the [`end()`](end.md) iterator) and all references to the elements are invalidated. Otherwise, only the +[`end()`](end.md) iterator is invalidated. + +For [`ordered_json`](../ordered_json.md), also adding an element to an **object** can yield a reallocation which again +invalidates all iterators and all references. + +## Parameters + +`val` (in) +: the value to add to the JSON array/object + +`init` (in) +: an initializer list + +## Exceptions + +1. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON array or null; example: `"cannot use push_back() with number"` +2. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON object or null; example: `"cannot use push_back() with number"` +3. Throws [`type_error.308`](../../home/exceptions.md#jsonexceptiontype_error308) when called on a type other than + JSON array or null; example: `"cannot use push_back() with number"` + +## Complexity + +1. Amortized constant. +2. Logarithmic in the size of the container, O(log(`size()`)). +3. Linear in the size of the initializer list `init`. + +## Notes + +(3) This function is required to resolve an ambiguous overload error, because pairs like `{"key", "value"}` can be both + interpreted as `object_t::value_type` or `std::initializer_list`, see + [#235](https://github.com/nlohmann/json/issues/235) for more information. + +## Examples + +??? example "Example: (1) add element to array" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value + was silently converted to a JSON array. + + ```cpp + --8<-- "examples/push_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back.output" + ``` + +??? example "Example: (2) add element to object" + + The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value + was silently converted to a JSON object. + + ```cpp + --8<-- "examples/push_back__object_t__value.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__object_t__value.output" + ``` + +??? example "Example: (3) add to object from initializer list" + + The example shows how initializer lists are treated as objects when possible. + + ```cpp + --8<-- "examples/push_back__initializer_list.cpp" + ``` + + Output: + + ```json + --8<-- "examples/push_back__initializer_list.output" + ``` + +## See also + +- [emplace_back](emplace_back.md) add a value to an array +- [operator+=](operator+=.md) add a value to an array/object +- [Modifying values](../../features/modifying_values.md) - the article on modifying values + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +3. Since version 2.0.0. diff --git a/api/basic_json/push_back/index.html b/api/basic_json/push_back/index.html index 2ab60fef4..4376dfdac 100644 --- a/api/basic_json/push_back/index.html +++ b/api/basic_json/push_back/index.html @@ -96,4 +96,4 @@ null {"four":4,"one":1,"three":3,"two":2} [["five",5]] -

See also

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.0.0.
\ No newline at end of file +

See also

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/push_back/index.md b/api/basic_json/push_back/index.md new file mode 100644 index 000000000..7e08d6c12 --- /dev/null +++ b/api/basic_json/push_back/index.md @@ -0,0 +1,192 @@ +# nlohmann::basic_json::push_back + +``` +// (1) +void push_back(basic_json&& val); +void push_back(const basic_json& val); + +// (2) +void push_back(const typename object_t::value_type& val); + +// (3) +void push_back(initializer_list_t init); +``` + +1. Appends the given element `val` to the end of the JSON array. If the function is called on a JSON null value, an empty array is created before appending `val`. + +1. Inserts the given element `val` to the JSON object. If the function is called on a JSON null value, an empty object is created before inserting `val`. + +1. This function allows using `push_back` with an initializer list. In case + + 1. the current value is an object, + 1. the initializer list `init` contains only two elements, and + 1. the first element of `init` is a string, + + `init` is converted into an object element and added using `push_back(const typename object_t::value_type&)`. Otherwise, `init` is converted to a JSON value and added using `push_back(basic_json&&)`. + +## Iterator invalidation + +For all cases where an element is added to an **array**, a reallocation can happen, in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. Otherwise, only the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator is invalidated. + +For [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), also adding an element to an **object** can yield a reallocation which again invalidates all iterators and all references. + +## Parameters + +`val` (in) : the value to add to the JSON array/object + +`init` (in) : an initializer list + +## Exceptions + +1. Throws [`type_error.308`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error308) when called on a type other than JSON array or null; example: `"cannot use push_back() with number"` +1. Throws [`type_error.308`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error308) when called on a type other than JSON object or null; example: `"cannot use push_back() with number"` +1. Throws [`type_error.308`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error308) when called on a type other than JSON array or null; example: `"cannot use push_back() with number"` + +## Complexity + +1. Amortized constant. +1. Logarithmic in the size of the container, O(log(`size()`)). +1. Linear in the size of the initializer list `init`. + +## Notes + +(3) This function is required to resolve an ambiguous overload error, because pairs like `{"key", "value"}` can be both interpreted as `object_t::value_type` or `std::initializer_list`, see [#235](https://github.com/nlohmann/json/issues/235) for more information. + +## Examples + +Example: (1) add element to array + +The example shows how `push_back()` and `+=` can be used to add elements to a JSON array. Note how the `null` value was silently converted to a JSON array. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json array = {1, 2, 3, 4, 5}; + json null; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; + + // add values + array.push_back(6); + array += 7; + null += "first"; + null += "second"; + + // print values + std::cout << array << '\n'; + std::cout << null << '\n'; +} +``` + +Output: + +``` +[1,2,3,4,5] +null +[1,2,3,4,5,6,7] +["first","second"] +``` + +Example: (2) add element to object + +The example shows how `push_back()` and `+=` can be used to add elements to a JSON object. Note how the `null` value was silently converted to a JSON object. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values + object.push_back(json::object_t::value_type("three", 3)); + object += json::object_t::value_type("four", 4); + null += json::object_t::value_type("A", "a"); + null += json::object_t::value_type("B", "b"); + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; +} +``` + +Output: + +``` +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +{"A":"a","B":"b"} +``` + +Example: (3) add to object from initializer list + +The example shows how initializer lists are treated as objects when possible. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json object = {{"one", 1}, {"two", 2}}; + json null; + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // add values: + object.push_back({"three", 3}); // object is extended + object += {"four", 4}; // object is extended + null.push_back({"five", 5}); // null is converted to array + + // print values + std::cout << object << '\n'; + std::cout << null << '\n'; + + // would throw: + //object.push_back({1, 2, 3}); +} +``` + +Output: + +``` +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +[["five",5]] +``` + +## See also + +- [emplace_back](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) add a value to an array +- [operator+=](https://json.nlohmann.me/api/basic_json/operator%2B%3D/index.md) add a value to an array/object +- [Modifying values](https://json.nlohmann.me/features/modifying_values/index.md) - the article on modifying values + +## Version history + +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 2.0.0. diff --git a/api/basic_json/rbegin.md b/api/basic_json/rbegin.md new file mode 100644 index 000000000..5fbbe7d3b --- /dev/null +++ b/api/basic_json/rbegin.md @@ -0,0 +1,42 @@ +# nlohmann::basic_json::rbegin + +```cpp +reverse_iterator rbegin() noexcept; +const_reverse_iterator rbegin() const noexcept; +``` + +Returns an iterator to the reverse-beginning; that is, the last element. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `rbegin()`. + + ```cpp + --8<-- "examples/rbegin.cpp" + ``` + + Output: + + ```json + --8<-- "examples/rbegin.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/rbegin/index.html b/api/basic_json/rbegin/index.html index 87a7c62cf..2bb674877 100644 --- a/api/basic_json/rbegin/index.html +++ b/api/basic_json/rbegin/index.html @@ -17,4 +17,4 @@ std::cout << *it << '\n'; }

Output:

5
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/rbegin/index.md b/api/basic_json/rbegin/index.md new file mode 100644 index 000000000..a26582176 --- /dev/null +++ b/api/basic_json/rbegin/index.md @@ -0,0 +1,55 @@ +# nlohmann::basic_json::rbegin + +``` +reverse_iterator rbegin() noexcept; +const_reverse_iterator rbegin() const noexcept; +``` + +Returns an iterator to the reverse-beginning; that is, the last element. + +## Return value + +reverse iterator to the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `rbegin()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-beginning + json::reverse_iterator it = array.rbegin(); + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +5 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/rend.md b/api/basic_json/rend.md new file mode 100644 index 000000000..8eb1a6e55 --- /dev/null +++ b/api/basic_json/rend.md @@ -0,0 +1,43 @@ +# nlohmann::basic_json::rend + +```cpp +reverse_iterator rend() noexcept; +const_reverse_iterator rend() const noexcept; +``` + +Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, +attempting to access it results in undefined behavior. + +![Illustration from cppreference.com](../../images/range-rbegin-rend.svg) + +## Return value + +reverse iterator to the element following the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code shows an example for `rend()`. + + ```cpp + --8<-- "examples/rend.cpp" + ``` + + Output: + + ```json + --8<-- "examples/rend.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/rend/index.html b/api/basic_json/rend/index.html index c5a5ce6a9..c6454a33b 100644 --- a/api/basic_json/rend/index.html +++ b/api/basic_json/rend/index.html @@ -20,4 +20,4 @@ std::cout << *it << '\n'; }

Output:

1
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/rend/index.md b/api/basic_json/rend/index.md new file mode 100644 index 000000000..b3b96d86f --- /dev/null +++ b/api/basic_json/rend/index.md @@ -0,0 +1,58 @@ +# nlohmann::basic_json::rend + +``` +reverse_iterator rend() noexcept; +const_reverse_iterator rend() const noexcept; +``` + +Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior. + +## Return value + +reverse iterator to the element following the last element + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code shows an example for `rend()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create an array value + json array = {1, 2, 3, 4, 5}; + + // get an iterator to the reverse-end + json::reverse_iterator it = array.rend(); + + // increment the iterator to point to the first element + --it; + + // serialize the element that the iterator points to + std::cout << *it << '\n'; +} +``` + +Output: + +``` +1 +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/sax_parse.md b/api/basic_json/sax_parse.md new file mode 100644 index 000000000..f0900941c --- /dev/null +++ b/api/basic_json/sax_parse.md @@ -0,0 +1,135 @@ +# nlohmann::basic_json::sax_parse + +```cpp +// (1) +template +static bool sax_parse(InputType&& i, + SAX* sax, + input_format_t format = input_format_t::json, + const bool strict = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); + +// (2) +template +static bool sax_parse(IteratorType first, IteratorType last, + SAX* sax, + input_format_t format = input_format_t::json, + const bool strict = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +Read from input and generate SAX events + +1. Read from a compatible input. +2. Read from a pair of character iterators + + The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted + respectively as UTF-8, UTF-16, and UTF-32. + +The SAX event lister must follow the interface of [`json_sax`](../json_sax/index.md). + +## Template parameters + +`InputType` +: A compatible input, for instance: + + - an `std::istream` object + - a `FILE` pointer + - a C-style array of characters + - a pointer to a null-terminated string of single byte characters + - an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of + iterators. + +`IteratorType` +: a compatible iterator type for overload (2); a pair of character iterators whose `value_type` is an integral type + with a size of 1, 2, or 4 bytes (interpreted respectively as UTF-8, UTF-16, and UTF-32) + +`SAX` +: a class fulfilling the SAX event listener interface; see [`json_sax`](../json_sax/index.md) + +## Parameters + +`i` (in) +: Input to parse from + +`sax` (in) +: SAX event listener (must not be null) + +`format` (in) +: the format to parse (JSON, CBOR, MessagePack, or UBJSON) (optional, `input_format_t::json` by default), see + [`input_format_t`](input_format_t.md) for more information + +`strict` (in) +: whether the input has to be consumed completely (optional, `#!cpp true` by default) + +`ignore_comments` (in) +: whether comments should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`ignore_trailing_commas` (in) +: whether trailing commas in arrays or objects should be ignored and treated like whitespace (`#!cpp true`) or yield a parse error + (`#!cpp false`); (optional, `#!cpp false` by default) + +`first` (in) +: iterator to the start of a character range + +`last` (in) +: iterator to the end of a character range + +## Return value + +return value of the last processed SAX event + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token, or + empty input like a null `FILE*` or `char*` pointer. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the SAX +consumer `sax` has a super-linear complexity. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +## Examples + +??? example + + The example below demonstrates the `sax_parse()` function reading from string and processing the events with a + user-defined SAX event consumer. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## See also + +- [parse](parse.md) - deserialize from a compatible input +- [accept](accept.md) - check if the input is valid JSON + +## Version history + +- Added in version 3.2.0. +- Ignoring comments via `ignore_comments` added in version 3.9.0. +- Added `ignore_trailing_commas` in version 3.12.x. + +!!! warning "Deprecation" + + Overload (2) replaces calls to `sax_parse` with a pair of iterators as their first parameter which has been + deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like + `#!cpp sax_parse({ptr, ptr+len});` with `#!cpp sax_parse(ptr, ptr+len);`. diff --git a/api/basic_json/sax_parse/index.html b/api/basic_json/sax_parse/index.html index 3b6d2c083..b21e00465 100644 --- a/api/basic_json/sax_parse/index.html +++ b/api/basic_json/sax_parse/index.html @@ -183,4 +183,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

See also

  • parse - deserialize from a compatible input
  • accept - check if the input is valid JSON

Version history

  • Added in version 3.2.0.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Added ignore_trailing_commas in version 3.12.x.

Deprecation

Overload (2) replaces calls to sax_parse with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like sax_parse({ptr, ptr+len}); with sax_parse(ptr, ptr+len);.

\ No newline at end of file +

See also

  • parse - deserialize from a compatible input
  • accept - check if the input is valid JSON

Version history

  • Added in version 3.2.0.
  • Ignoring comments via ignore_comments added in version 3.9.0.
  • Added ignore_trailing_commas in version 3.12.x.

Deprecation

Overload (2) replaces calls to sax_parse with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like sax_parse({ptr, ptr+len}); with sax_parse(ptr, ptr+len);.

\ No newline at end of file diff --git a/api/basic_json/sax_parse/index.md b/api/basic_json/sax_parse/index.md new file mode 100644 index 000000000..dac4aa138 --- /dev/null +++ b/api/basic_json/sax_parse/index.md @@ -0,0 +1,283 @@ +# nlohmann::basic_json::sax_parse + +``` +// (1) +template +static bool sax_parse(InputType&& i, + SAX* sax, + input_format_t format = input_format_t::json, + const bool strict = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); + +// (2) +template +static bool sax_parse(IteratorType first, IteratorType last, + SAX* sax, + input_format_t format = input_format_t::json, + const bool strict = true, + const bool ignore_comments = false, + const bool ignore_trailing_commas = false); +``` + +Read from input and generate SAX events + +1. Read from a compatible input. + +1. Read from a pair of character iterators + + The value_type of the iterator must be an integral type with a size of 1, 2, or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16, and UTF-32. + +The SAX event lister must follow the interface of [`json_sax`](https://json.nlohmann.me/api/json_sax/index.md). + +## Template parameters + +`InputType` : A compatible input, for instance: + +``` +- an `std::istream` object +- a `FILE` pointer +- a C-style array of characters +- a pointer to a null-terminated string of single byte characters +- an object `obj` for which `begin(obj)` and `end(obj)` produces a valid pair of + iterators. +``` + +`IteratorType` : a compatible iterator type for overload (2); a pair of character iterators whose `value_type` is an integral type with a size of 1, 2, or 4 bytes (interpreted respectively as UTF-8, UTF-16, and UTF-32) + +`SAX` : a class fulfilling the SAX event listener interface; see [`json_sax`](https://json.nlohmann.me/api/json_sax/index.md) + +## Parameters + +`i` (in) : Input to parse from + +`sax` (in) : SAX event listener (must not be null) + +`format` (in) : the format to parse (JSON, CBOR, MessagePack, or UBJSON) (optional, `input_format_t::json` by default), see [`input_format_t`](https://json.nlohmann.me/api/basic_json/input_format_t/index.md) for more information + +`strict` (in) : whether the input has to be consumed completely (optional, `true` by default) + +`ignore_comments` (in) : whether comments should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default) + +`ignore_trailing_commas` (in) : whether trailing commas in arrays or objects should be ignored and treated like whitespace (`true`) or yield a parse error (`false`); (optional, `false` by default) + +`first` (in) : iterator to the start of a character range + +`last` (in) : iterator to the end of a character range + +## Return value + +return value of the last processed SAX event + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`parse_error.101`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error101) in case of an unexpected token, or empty input like a null `FILE*` or `char*` pointer. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the SAX consumer `sax` has a super-linear complexity. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +## Examples + +Example + +The example below demonstrates the `sax_parse()` function reading from string and processing the events with a user-defined SAX event consumer. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## See also + +- [parse](https://json.nlohmann.me/api/basic_json/parse/index.md) - deserialize from a compatible input +- [accept](https://json.nlohmann.me/api/basic_json/accept/index.md) - check if the input is valid JSON + +## Version history + +- Added in version 3.2.0. +- Ignoring comments via `ignore_comments` added in version 3.9.0. +- Added `ignore_trailing_commas` in version 3.12.x. + +Deprecation + +Overload (2) replaces calls to `sax_parse` with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like `sax_parse({ptr, ptr+len});` with `sax_parse(ptr, ptr+len);`. diff --git a/api/basic_json/size.md b/api/basic_json/size.md new file mode 100644 index 000000000..4ff582db2 --- /dev/null +++ b/api/basic_json/size.md @@ -0,0 +1,57 @@ +# nlohmann::basic_json::size + +```cpp +size_type size() const noexcept; +``` + +Returns the number of elements in a JSON value. + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +|------------|-------------------------------------| +| null | `0` | +| boolean | `1` | +| string | `1` | +| number | `1` | +| binary | `1` | +| object | result of function object_t::size() | +| array | result of function array_t::size() | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](array_t.md) and [`object_t`](object_t.md) satisfy the +[Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `size()` functions have +constant complexity. + +## Notes + +This function does not return the length of a string stored as JSON value -- it returns the number of elements in the +JSON value which is `1` in the case of a string. + +## Examples + +??? example + + The following code calls `size()` on the different value types. + + ```cpp + --8<-- "examples/size.cpp" + ``` + + Output: + + ```json + --8<-- "examples/size.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Extended to return `1` for binary types in version 3.8.0. diff --git a/api/basic_json/size/index.html b/api/basic_json/size/index.html index cb44b762d..1f019fdd6 100644 --- a/api/basic_json/size/index.html +++ b/api/basic_json/size/index.html @@ -37,4 +37,4 @@ 5 0 1 -

Version history

  • Added in version 1.0.0.
  • Extended to return 1 for binary types in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
  • Extended to return 1 for binary types in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/size/index.md b/api/basic_json/size/index.md new file mode 100644 index 000000000..9b0add209 --- /dev/null +++ b/api/basic_json/size/index.md @@ -0,0 +1,90 @@ +# nlohmann::basic_json::size + +``` +size_type size() const noexcept; +``` + +Returns the number of elements in a JSON value. + +## Return value + +The return value depends on the different types and is defined as follows: + +| Value type | return value | +| ---------- | ----------------------------------- | +| null | `0` | +| boolean | `1` | +| string | `1` | +| number | `1` | +| binary | `1` | +| object | result of function object_t::size() | +| array | result of function array_t::size() | + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant, as long as [`array_t`](https://json.nlohmann.me/api/basic_json/array_t/index.md) and [`object_t`](https://json.nlohmann.me/api/basic_json/object_t/index.md) satisfy the [Container](https://en.cppreference.com/w/cpp/named_req/Container) concept; that is, their `size()` functions have constant complexity. + +## Notes + +This function does not return the length of a string stored as JSON value -- it returns the number of elements in the JSON value which is `1` in the case of a string. + +## Examples + +Example + +The following code calls `size()` on the different value types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = 17; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_object_empty(json::value_t::object); + json j_array = {1, 2, 4, 8, 16}; + json j_array_empty(json::value_t::array); + json j_string = "Hello, world"; + + // call size() + std::cout << j_null.size() << '\n'; + std::cout << j_boolean.size() << '\n'; + std::cout << j_number_integer.size() << '\n'; + std::cout << j_number_float.size() << '\n'; + std::cout << j_object.size() << '\n'; + std::cout << j_object_empty.size() << '\n'; + std::cout << j_array.size() << '\n'; + std::cout << j_array_empty.size() << '\n'; + std::cout << j_string.size() << '\n'; +} +``` + +Output: + +``` +0 +1 +1 +1 +2 +0 +5 +0 +1 +``` + +## Version history + +- Added in version 1.0.0. +- Extended to return `1` for binary types in version 3.8.0. diff --git a/api/basic_json/start_pos.md b/api/basic_json/start_pos.md new file mode 100644 index 000000000..19a31df15 --- /dev/null +++ b/api/basic_json/start_pos.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::start_pos + +```cpp +#if JSON_DIAGNOSTIC_POSITIONS +constexpr std::size_t start_pos() const noexcept; +#endif +``` + +Returns the position of the first character in the JSON string from which the value was parsed from. + +| JSON type | return value | +|-----------|------------------------------------------------| +| object | position of the opening `{` | +| array | position of the opening `[` | +| string | position of the opening `"` | +| number | position of the first character | +| boolean | position of `t` for `true` and `f` for `false` | +| null | position of `n` | + +## Return value + +the position of the first character of the value in the parsed JSON string, if the value was created by the +[`parse`](parse.md) function, or `std::string::npos` if the value was constructed otherwise + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +!!! note "Note" + + The function is only available if macro [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) has + been defined to `#!cpp 1` before including the library header. + +!!! warning "Invalidation" + + The returned positions are only valid as long as the JSON value is not changed. The positions are *not* updated + when the JSON value is changed. + +## Examples + +??? example "Example" + + ```cpp + --8<-- "examples/diagnostic_positions.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostic_positions.output" + ``` + + The output shows the start/end positions of all the objects and fields in the JSON string. + +## See also + +- [end_pos](end_pos.md) to access the end position +- [JSON_DIAGNOSTIC_POSITIONS](../macros/json_diagnostic_positions.md) for an overview of the diagnostic positions + +## Version history + +- Added in version 3.12.0. diff --git a/api/basic_json/start_pos/index.html b/api/basic_json/start_pos/index.html index aa3af1bd1..35cc4b8a8 100644 --- a/api/basic_json/start_pos/index.html +++ b/api/basic_json/start_pos/index.html @@ -101,4 +101,4 @@ Original string: 1 Parsed string: 1 -

The output shows the start/end positions of all the objects and fields in the JSON string.

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file +

The output shows the start/end positions of all the objects and fields in the JSON string.

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file diff --git a/api/basic_json/start_pos/index.md b/api/basic_json/start_pos/index.md new file mode 100644 index 000000000..d19d59f8f --- /dev/null +++ b/api/basic_json/start_pos/index.md @@ -0,0 +1,163 @@ +# nlohmann::basic_json::start_pos + +``` +#if JSON_DIAGNOSTIC_POSITIONS +constexpr std::size_t start_pos() const noexcept; +#endif +``` + +Returns the position of the first character in the JSON string from which the value was parsed from. + +| JSON type | return value | +| --------- | ---------------------------------------------- | +| object | position of the opening `{` | +| array | position of the opening `[` | +| string | position of the opening `"` | +| number | position of the first character | +| boolean | position of `t` for `true` and `f` for `false` | +| null | position of `n` | + +## Return value + +the position of the first character of the value in the parsed JSON string, if the value was created by the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function, or `std::string::npos` if the value was constructed otherwise + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Notes + +Note + +The function is only available if macro [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) has been defined to `1` before including the library header. + +Invalidation + +The returned positions are only valid as long as the JSON value is not changed. The positions are *not* updated when the JSON value is changed. + +## Examples + +Example + +``` +#include + +#define JSON_DIAGNOSTIC_POSITIONS 1 +#include + +using json = nlohmann::json; + +int main() +{ + std::string json_string = R"( + { + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } + )"; + json j = json::parse(json_string); + + std::cout << "Root diagnostic positions: \n"; + std::cout << "\tstart_pos: " << j.start_pos() << '\n'; + std::cout << "\tend_pos:" << j.end_pos() << "\n"; + std::cout << "Original string: \n"; + std::cout << "{\n \"address\": {\n \"street\": \"Fake Street\",\n \"housenumber\": 1\n }\n }" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << "\n\n"; + + std::cout << "address diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "{ \"street\": \"Fake Street\",\n \"housenumber\": 1\n }" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"].start_pos(), j["address"].end_pos() - j["address"].start_pos()) << "\n\n"; + + std::cout << "street diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"]["street"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"]["street"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "\"Fake Street\"" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"]["street"].start_pos(), j["address"]["street"].end_pos() - j["address"]["street"].start_pos()) << "\n\n"; + + std::cout << "housenumber diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"]["housenumber"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"]["housenumber"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "1" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"]["housenumber"].start_pos(), j["address"]["housenumber"].end_pos() - j["address"]["housenumber"].start_pos()) << "\n\n"; +} +``` + +Output: + +``` +Root diagnostic positions: + start_pos: 5 + end_pos:109 +Original string: +{ + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } +Parsed string: +{ + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } + +address diagnostic positions: + start_pos:26 + end_pos:103 + +Original string: +{ "street": "Fake Street", + "housenumber": 1 + } +Parsed string: +{ + "street": "Fake Street", + "housenumber": 1 + } + +street diagnostic positions: + start_pos:50 + end_pos:63 + +Original string: +"Fake Street" +Parsed string: +"Fake Street" + +housenumber diagnostic positions: + start_pos:92 + end_pos:93 + +Original string: +1 +Parsed string: +1 +``` + +The output shows the start/end positions of all the objects and fields in the JSON string. + +## See also + +- [end_pos](https://json.nlohmann.me/api/basic_json/end_pos/index.md) to access the end position +- [JSON_DIAGNOSTIC_POSITIONS](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) for an overview of the diagnostic positions + +## Version history + +- Added in version 3.12.0. diff --git a/api/basic_json/std_formatter.md b/api/basic_json/std_formatter.md new file mode 100644 index 000000000..be1d2d22e --- /dev/null +++ b/api/basic_json/std_formatter.md @@ -0,0 +1,57 @@ +# std::formatter + +```cpp +namespace std { + template <> + struct formatter; +} +``` + +Specialization to make JSON values formattable with [`std::format`](https://en.cppreference.com/w/cpp/utility/format/format) +(and the other members of C++20's `` header, such as `std::format_to`). + +A subset of the [standard format spec grammar](https://en.cppreference.com/w/cpp/utility/format/spec) is +supported, repurposed for JSON pretty-printing; any other spec component (sign, the `0` flag, precision, +`L`, a dynamic width such as `#!cpp "{:{}}"`, or a trailing type character) throws +[`std::format_error`](https://en.cppreference.com/w/cpp/utility/format/format_error): + +- `#!cpp "{}"` serializes the value the same way as [`dump()`](dump.md) (compact, no whitespace). +- `#!cpp "{:#}"` ("alternate form") serializes the value the same way as `#!cpp dump(4)` (pretty-printed + with an indent of 4). +- A width, with or without `#!cpp "#"` (e.g. `#!cpp "{:2}"` or `#!cpp "{:#2}"`), serializes the value the + same way as `#!cpp dump(width)` — a width on its own implies pretty-printing, since an indent size has + no meaning for compact output. +- `fill-and-align` (e.g. `#!cpp "{:.>#}"` or `#!cpp "{:.>3}"`) picks a custom indent character, the same + way as `#!cpp dump(indent, indent_char)`. The alignment direction itself (`#!cpp '<'`, `#!cpp '>'`, + `#!cpp '^'`) has no separate meaning for JSON values — only the fill character before it is used, and + any of the three directions is accepted. + +This specialization is only available for `#!cpp char`-based JSON values and only if the standard library +provides ``, controlled by the [`JSON_HAS_STD_FORMAT`](../macros/json_has_std_format.md) macro. + +## Examples + +??? example + + The example shows how to format JSON values with `std::format`. + + ```cpp + --8<-- "examples/std_formatter.c++20.cpp" + ``` + + Output: + + ```json + --8<-- "examples/std_formatter.c++20.output" + ``` + +## See also + +- [dump](dump.md) - serialization +- [operator<<(std::ostream&)](../operator_ltlt.md) - serialize to stream +- [format_as](format_as.md) - customization point used by `fmt::format` (fmtlib) +- [Serialization](../../features/serialization.md) - the serialization article + +## Version history + +- Added in version 3.12.x. diff --git a/api/basic_json/std_formatter/index.html b/api/basic_json/std_formatter/index.html index e6dc58637..57782410f 100644 --- a/api/basic_json/std_formatter/index.html +++ b/api/basic_json/std_formatter/index.html @@ -40,4 +40,4 @@ ...."one": 1, ...."two": 2 } -

See also

Version history

  • Added in version 3.12.x.
\ No newline at end of file +

See also

Version history

  • Added in version 3.12.x.
\ No newline at end of file diff --git a/api/basic_json/std_formatter/index.md b/api/basic_json/std_formatter/index.md new file mode 100644 index 000000000..ec0747d06 --- /dev/null +++ b/api/basic_json/std_formatter/index.md @@ -0,0 +1,82 @@ +# std::formatter + +``` +namespace std { + template <> + struct formatter; +} +``` + +Specialization to make JSON values formattable with [`std::format`](https://en.cppreference.com/w/cpp/utility/format/format) (and the other members of C++20's `` header, such as `std::format_to`). + +A subset of the [standard format spec grammar](https://en.cppreference.com/w/cpp/utility/format/spec) is supported, repurposed for JSON pretty-printing; any other spec component (sign, the `0` flag, precision, `L`, a dynamic width such as `"{:{}}"`, or a trailing type character) throws [`std::format_error`](https://en.cppreference.com/w/cpp/utility/format/format_error): + +- `"{}"` serializes the value the same way as [`dump()`](https://json.nlohmann.me/api/basic_json/dump/index.md) (compact, no whitespace). +- `"{:#}"` ("alternate form") serializes the value the same way as `dump(4)` (pretty-printed with an indent of 4). +- A width, with or without `"#"` (e.g. `"{:2}"` or `"{:#2}"`), serializes the value the same way as `dump(width)` — a width on its own implies pretty-printing, since an indent size has no meaning for compact output. +- `fill-and-align` (e.g. `"{:.>#}"` or `"{:.>3}"`) picks a custom indent character, the same way as `dump(indent, indent_char)`. The alignment direction itself (`'<'`, `'>'`, `'^'`) has no separate meaning for JSON values — only the fill character before it is used, and any of the three directions is accepted. + +This specialization is only available for `char`-based JSON values and only if the standard library provides ``, controlled by the [`JSON_HAS_STD_FORMAT`](https://json.nlohmann.me/api/macros/json_has_std_format/index.md) macro. + +## Examples + +Example + +The example shows how to format JSON values with `std::format`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j = {{"one", 1}, {"two", 2}}; + + // compact formatting, like dump() + std::cout << std::format("{}", j) << "\n\n"; + + // pretty-printed formatting, like dump(4) + std::cout << std::format("{:#}", j) << "\n\n"; + + // a width sets the indent, like dump(2) + std::cout << std::format("{:2}", j) << "\n\n"; + + // fill-and-align sets the indent character, like dump(4, '.') + std::cout << std::format("{:.>#}", j) << std::endl; +} +``` + +Output: + +``` +{"one":1,"two":2} + +{ + "one": 1, + "two": 2 +} + +{ + "one": 1, + "two": 2 +} + +{ +...."one": 1, +...."two": 2 +} +``` + +## See also + +- [dump](https://json.nlohmann.me/api/basic_json/dump/index.md) - serialization +- [operator\<<(std::ostream&)](https://json.nlohmann.me/api/operator_ltlt/index.md) - serialize to stream +- [format_as](https://json.nlohmann.me/api/basic_json/format_as/index.md) - customization point used by `fmt::format` (fmtlib) +- [Serialization](https://json.nlohmann.me/features/serialization/index.md) - the serialization article + +## Version history + +- Added in version 3.12.x. diff --git a/api/basic_json/std_hash.md b/api/basic_json/std_hash.md new file mode 100644 index 000000000..b9de74f8c --- /dev/null +++ b/api/basic_json/std_hash.md @@ -0,0 +1,34 @@ +# std::hash + +```cpp +namespace std { + struct hash; +} +``` + +Return a hash value for a JSON object. The hash function tries to rely on `std::hash` where possible. Furthermore, the +type of the JSON value is taken into account to have different hash values for `#!json null`, `#!cpp 0`, `#!cpp 0U`, and +`#!cpp false`, etc. + +## Examples + +??? example + + The example shows how to calculate hash values for different JSON values. + + ```cpp + --8<-- "examples/std_hash.cpp" + ``` + + Output: + + ```json + --8<-- "examples/std_hash.output" + ``` + + Note the output is platform-dependent. + +## Version history + +- Added in version 1.0.0. +- Extended for arbitrary basic_json types in version 3.10.5. diff --git a/api/basic_json/std_hash/index.html b/api/basic_json/std_hash/index.html index 579c06aa9..fa38a82f5 100644 --- a/api/basic_json/std_hash/index.html +++ b/api/basic_json/std_hash/index.html @@ -28,4 +28,4 @@ hash({}) = 2654435832 hash([]) = 2654435899 hash({"hello": "world"}) = 4469488738203676328 -

Note the output is platform-dependent.

Version history

  • Added in version 1.0.0.
  • Extended for arbitrary basic_json types in version 3.10.5.
\ No newline at end of file +

Note the output is platform-dependent.

Version history

  • Added in version 1.0.0.
  • Extended for arbitrary basic_json types in version 3.10.5.
\ No newline at end of file diff --git a/api/basic_json/std_hash/index.md b/api/basic_json/std_hash/index.md new file mode 100644 index 000000000..7e9ef2b8d --- /dev/null +++ b/api/basic_json/std_hash/index.md @@ -0,0 +1,57 @@ +# std::hash + +``` +namespace std { + struct hash; +} +``` + +Return a hash value for a JSON object. The hash function tries to rely on `std::hash` where possible. Furthermore, the type of the JSON value is taken into account to have different hash values for `null`, `0`, `0U`, and `false`, etc. + +## Examples + +Example + +The example shows how to calculate hash values for different JSON values. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + std::cout << "hash(null) = " << std::hash {}(json(nullptr)) << '\n' + << "hash(false) = " << std::hash {}(json(false)) << '\n' + << "hash(0) = " << std::hash {}(json(0)) << '\n' + << "hash(0U) = " << std::hash {}(json(0U)) << '\n' + << "hash(\"\") = " << std::hash {}(json("")) << '\n' + << "hash({}) = " << std::hash {}(json::object()) << '\n' + << "hash([]) = " << std::hash {}(json::array()) << '\n' + << "hash({\"hello\": \"world\"}) = " << std::hash {}("{\"hello\": \"world\"}"_json) + << std::endl; +} +``` + +Output: + +``` +hash(null) = 2654435769 +hash(false) = 2654436030 +hash(0) = 2654436095 +hash(0U) = 2654436156 +hash("") = 6142509191626859748 +hash({}) = 2654435832 +hash([]) = 2654435899 +hash({"hello": "world"}) = 4469488738203676328 +``` + +Note the output is platform-dependent. + +## Version history + +- Added in version 1.0.0. +- Extended for arbitrary basic_json types in version 3.10.5. diff --git a/api/basic_json/std_swap.md b/api/basic_json/std_swap.md new file mode 100644 index 000000000..f93830ff4 --- /dev/null +++ b/api/basic_json/std_swap.md @@ -0,0 +1,59 @@ +# std::swap + +```cpp +namespace std { + void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2); +} +``` + +Exchanges the values of two JSON objects. + +## Parameters + +`j1` (in, out) +: value to be replaced by `j2` + +`j2` (in, out) +: value to be replaced by `j1` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +```cpp +void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2) +{ + j1.swap(j2); +} +``` + +## Examples + +??? example + + The following code shows how two values are swapped with `std::swap`. + + ```cpp + --8<-- "examples/std_swap.cpp" + ``` + + Output: + + ```json + --8<-- "examples/std_swap.output" + ``` + +## See also + +- [swap](swap.md) + +## Version history + +- Added in version 1.0.0. +- Extended for arbitrary basic_json types in version 3.10.5. diff --git a/api/basic_json/std_swap/index.html b/api/basic_json/std_swap/index.html index 6cf174260..10fd3ac41 100644 --- a/api/basic_json/std_swap/index.html +++ b/api/basic_json/std_swap/index.html @@ -26,4 +26,4 @@ }

Output:

j1 = {"one":1,"two":2} | j2 = [1,2,4,8,16]
 j1 = [1,2,4,8,16] | j2 = {"one":1,"two":2}
-

See also

Version history

  • Added in version 1.0.0.
  • Extended for arbitrary basic_json types in version 3.10.5.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
  • Extended for arbitrary basic_json types in version 3.10.5.
\ No newline at end of file diff --git a/api/basic_json/std_swap/index.md b/api/basic_json/std_swap/index.md new file mode 100644 index 000000000..2b8a5a754 --- /dev/null +++ b/api/basic_json/std_swap/index.md @@ -0,0 +1,76 @@ +# std::swap\ + +``` +namespace std { + void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2); +} +``` + +Exchanges the values of two JSON objects. + +## Parameters + +`j1` (in, out) : value to be replaced by `j2` + +`j2` (in, out) : value to be replaced by `j1` + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Possible implementation + +``` +void swap(nlohmann::basic_json& j1, nlohmann::basic_json& j2) +{ + j1.swap(j2); +} +``` + +## Examples + +Example + +The following code shows how two values are swapped with `std::swap`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j1 = {{"one", 1}, {"two", 2}}; + json j2 = {1, 2, 4, 8, 16}; + + std::cout << "j1 = " << j1 << " | j2 = " << j2 << '\n'; + + // swap values + std::swap(j1, j2); + + std::cout << "j1 = " << j1 << " | j2 = " << j2 << std::endl; +} +``` + +Output: + +``` +j1 = {"one":1,"two":2} | j2 = [1,2,4,8,16] +j1 = [1,2,4,8,16] | j2 = {"one":1,"two":2} +``` + +## See also + +- [swap](https://json.nlohmann.me/api/basic_json/swap/index.md) + +## Version history + +- Added in version 1.0.0. +- Extended for arbitrary basic_json types in version 3.10.5. diff --git a/api/basic_json/string_t.md b/api/basic_json/string_t.md new file mode 100644 index 000000000..dc85fcd4d --- /dev/null +++ b/api/basic_json/string_t.md @@ -0,0 +1,66 @@ +# nlohmann::basic_json::string_t + +```cpp +using string_t = StringType; +``` + +The type used to store JSON strings. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: +> A string is a sequence of zero or more Unicode characters. + +To store strings in C++, a type is defined by the template parameter described below. Unicode values are split by the +JSON class into byte-sized characters during deserialization. + +## Template parameters + +`StringType` +: the container to store strings (e.g., `std::string`). Note this container is used for keys/names in objects, see + [object_t](object_t.md). + +## Notes + +#### Default type + +With the default values for `StringType` (`std::string`), the default value for `string_t` is `#!cpp std::string`. + +#### Encoding + +Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return +the number of bytes in the string rather than the number of characters or glyphs. + +#### String comparison + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: +> Software implementations are typically required to test names of object members for equality. Implementations that +> transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, +> code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or +> inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may +> incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal. + +This implementation is interoperable as it does compare strings code unit by code unit. + +#### Storage + +String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type +`string_t*` must be dereferenced. + +## Examples + +??? example + + The following code shows that `string_t` is by default, a typedef to `#!cpp std::string`. + + ```cpp + --8<-- "examples/string_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/string_t.output" + ``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/string_t/index.html b/api/basic_json/string_t/index.html index 406fda5af..b2b631b8b 100644 --- a/api/basic_json/string_t/index.html +++ b/api/basic_json/string_t/index.html @@ -10,4 +10,4 @@ std::cout << std::boolalpha << std::is_same<std::string, json::string_t>::value << std::endl; }

Output:

true
-

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/string_t/index.md b/api/basic_json/string_t/index.md new file mode 100644 index 000000000..7d9e3ada2 --- /dev/null +++ b/api/basic_json/string_t/index.md @@ -0,0 +1,68 @@ +# nlohmann::basic_json::string_t + +``` +using string_t = StringType; +``` + +The type used to store JSON strings. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: + +> A string is a sequence of zero or more Unicode characters. + +To store strings in C++, a type is defined by the template parameter described below. Unicode values are split by the JSON class into byte-sized characters during deserialization. + +## Template parameters + +`StringType` : the container to store strings (e.g., `std::string`). Note this container is used for keys/names in objects, see [object_t](https://json.nlohmann.me/api/basic_json/object_t/index.md). + +## Notes + +#### Default type + +With the default values for `StringType` (`std::string`), the default value for `string_t` is `std::string`. + +#### Encoding + +Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return the number of bytes in the string rather than the number of characters or glyphs. + +#### String comparison + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit, are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal. + +This implementation is interoperable as it does compare strings code unit by code unit. + +#### Storage + +String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type `string_t*` must be dereferenced. + +## Examples + +Example + +The following code shows that `string_t` is by default, a typedef to `std::string`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} +``` + +Output: + +``` +true +``` + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/swap.md b/api/basic_json/swap.md new file mode 100644 index 000000000..3a3d288fb --- /dev/null +++ b/api/basic_json/swap.md @@ -0,0 +1,169 @@ +# nlohmann::basic_json::swap + +```cpp +// (1) +void swap(reference other) noexcept ( + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value +); + +// (2) +friend void swap(reference left, reference right) noexcept ( + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::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); +``` + +1. 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. +2. Exchanges the contents of the JSON value from `left` with those of `right`. 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. +3. 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. +4. 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. +5. 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. +6. 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. +7. 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 + +1. No-throw guarantee: this function never throws exceptions. +2. No-throw guarantee: this function never throws exceptions. +3. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + arrays; example: `"cannot use swap(array_t&) with boolean"` +4. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + objects; example: `"cannot use swap(object_t&) with boolean"` +5. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + strings; example: `"cannot use swap(string_t&) with boolean"` +6. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if called on JSON values other than + binaries; example: `"cannot use swap(binary_t&) with boolean"` +7. Throws [`type_error.310`](../../home/exceptions.md#jsonexceptiontype_error310) if 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](std_swap.md) +- [operator=](operator=.md) copy assignment +- [basic_json](basic_json.md) create a JSON value + +## Version history + +1. Since version 1.0.0. +2. Since version 1.0.0. +3. Since version 1.0.0. +4. Since version 1.0.0. +5. Since version 1.0.0. +6. Since version 3.8.0. +7. Since version 3.8.0. \ No newline at end of file diff --git a/api/basic_json/swap/index.html b/api/basic_json/swap/index.html index 8c46c0339..b3cdda742 100644 --- a/api/basic_json/swap/index.html +++ b/api/basic_json/swap/index.html @@ -136,4 +136,4 @@ }

Output:

value = {"bytes":[4,5,6],"subtype":null}
 binary = {"bytes":[1,2,3],"subtype":null}
-

See also

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 1.0.0.
  4. Since version 1.0.0.
  5. Since version 1.0.0.
  6. Since version 3.8.0.
  7. Since version 3.8.0.
\ No newline at end of file +

See also

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 1.0.0.
  4. Since version 1.0.0.
  5. Since version 1.0.0.
  6. Since version 3.8.0.
  7. Since version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/swap/index.md b/api/basic_json/swap/index.md new file mode 100644 index 000000000..dd5bc9697 --- /dev/null +++ b/api/basic_json/swap/index.md @@ -0,0 +1,250 @@ +# nlohmann::basic_json::swap + +``` +// (1) +void swap(reference other) noexcept ( + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value +); + +// (2) +friend void swap(reference left, reference right) noexcept ( + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::value && + std::is_nothrow_move_constructible::value && + std::is_nothrow_move_assignable::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); +``` + +1. 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. +1. Exchanges the contents of the JSON value from `left` with those of `right`. 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. +1. 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. +1. 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. +1. 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. +1. 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. +1. 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 + +1. No-throw guarantee: this function never throws exceptions. +1. No-throw guarantee: this function never throws exceptions. +1. Throws [`type_error.310`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error310) if called on JSON values other than arrays; example: `"cannot use swap(array_t&) with boolean"` +1. Throws [`type_error.310`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error310) if called on JSON values other than objects; example: `"cannot use swap(object_t&) with boolean"` +1. Throws [`type_error.310`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error310) if called on JSON values other than strings; example: `"cannot use swap(string_t&) with boolean"` +1. Throws [`type_error.310`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error310) if called on JSON values other than binaries; example: `"cannot use swap(binary_t&) with boolean"` +1. Throws [`type_error.310`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error310) if called on JSON values other than binaries; example: `"cannot use swap(binary_t::container_type&) with boolean"` + +## Complexity + +Constant. + +## Examples + +Example: Swap JSON value (1, 2) + +The example below shows how JSON values can be swapped with `swap()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create two JSON values + json j1 = {1, 2, 3, 4, 5}; + json j2 = {{"pi", 3.141592653589793}, {"e", 2.718281828459045}}; + + // swap the values + j1.swap(j2); + + // output the values + std::cout << "j1 = " << j1 << '\n'; + std::cout << "j2 = " << j2 << '\n'; +} +``` + +Output: + +``` +j1 = {"e":2.718281828459045,"pi":3.141592653589793} +j2 = [1,2,3,4,5] +``` + +Example: Swap array (3) + +The example below shows how arrays can be swapped with `swap()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json value = {{"array", {1, 2, 3, 4}}}; + + // create an array_t + json::array_t array = {"Snap", "Crackle", "Pop"}; + + // swap the array stored in the JSON value + value["array"].swap(array); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "array = " << array << '\n'; +} +``` + +Output: + +``` +value = {"array":["Snap","Crackle","Pop"]} +array = [1,2,3,4] +``` + +Example: Swap object (4) + +The example below shows how objects can be swapped with `swap()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json value = { {"translation", {{"one", "eins"}, {"two", "zwei"}}} }; + + // create an object_t + json::object_t object = {{"cow", "Kuh"}, {"dog", "Hund"}}; + + // swap the object stored in the JSON value + value["translation"].swap(object); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "object = " << object << '\n'; +} +``` + +Output: + +``` +value = {"translation":{"cow":"Kuh","dog":"Hund"}} +object = {"one":"eins","two":"zwei"} +``` + +Example: Swap string (5) + +The example below shows how strings can be swapped with `swap()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value + json value = { "the good", "the bad", "the ugly" }; + + // create string_t + json::string_t string = "the fast"; + + // swap the object stored in the JSON value + value[1].swap(string); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "string = " << string << '\n'; +} +``` + +Output: + +``` +value = ["the good","the fast","the ugly"] +string = the bad +``` + +Example: Swap binary (6) + +The example below shows how binary values can be swapped with `swap()`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a binary value + json value = json::binary({1, 2, 3}); + + // create a binary_t + json::binary_t binary = {{4, 5, 6}}; + + // swap the object stored in the JSON value + value.swap(binary); + + // output the values + std::cout << "value = " << value << '\n'; + std::cout << "binary = " << json(binary) << '\n'; +} +``` + +Output: + +``` +value = {"bytes":[4,5,6],"subtype":null} +binary = {"bytes":[1,2,3],"subtype":null} +``` + +## See also + +- [std::swap\](https://json.nlohmann.me/api/basic_json/std_swap/index.md) +- [operator=](https://json.nlohmann.me/api/basic_json/operator%3D/index.md) copy assignment +- [basic_json](https://json.nlohmann.me/api/basic_json/basic_json/index.md) create a JSON value + +## Version history + +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 1.0.0. +1. Since version 3.8.0. +1. Since version 3.8.0. diff --git a/api/basic_json/to_bjdata.md b/api/basic_json/to_bjdata.md new file mode 100644 index 000000000..9c1efb183 --- /dev/null +++ b/api/basic_json/to_bjdata.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::to_bjdata + +```cpp +// (1) +static std::vector to_bjdata(const basic_json& j, + const bool use_size = false, + const bool use_type = false, + const bjdata_version_t version = bjdata_version_t::draft2); + +// (2) +static void to_bjdata(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false, + const bjdata_version_t version = bjdata_version_t::draft2); +static void to_bjdata(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false, + const bjdata_version_t version = bjdata_version_t::draft2); +``` + +Serializes a given JSON value `j` to a byte vector using the BJData (Binary JData) serialization format. BJData aims to +be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the BJData serialization. +2. Writes the BJData serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/bjdata.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +`use_size` (in) +: whether to add size annotations to container types; optional, `#!cpp false` by default. + +`use_type` (in) +: whether to add type annotations to container types (must be combined with `#!cpp use_size = true`); optional, +`#!cpp false` by default. + +`version` (in) +: which version of BJData to use (see note on "Binary values" on [BJData](../../features/binary_formats/bjdata.md)); +optional, `#!cpp bjdata_version_t::draft2` by default. + +## Return value + +1. BJData serialization as byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in BJData format. + + ```cpp + --8<-- "examples/to_bjdata.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_bjdata.output" + ``` + +## See also + +- [from_bjdata](from_bjdata.md) create a JSON value from an input in BJData format +- [to_cbor](to_cbor.md) create a CBOR serialization of a JSON value +- [to_msgpack](to_msgpack.md) create a MessagePack serialization of a JSON value +- [to_bson](to_bson.md) create a BSON serialization of a JSON value +- [to_ubjson](to_ubjson.md) create a UBJSON serialization of a JSON value + +## Version history + +- Added in version 3.11.0. +- BJData version parameter (for draft3 binary encoding) added in version 3.12.0. \ No newline at end of file diff --git a/api/basic_json/to_bjdata/index.html b/api/basic_json/to_bjdata/index.html index 1b9a33616..3c614ca65 100644 --- a/api/basic_json/to_bjdata/index.html +++ b/api/basic_json/to_bjdata/index.html @@ -79,4 +79,4 @@ [i1i2i3i4i5i6i7i8] [#i8i1i2i3i4i5i6i7i8 [$i#i812345678 -

See also

  • from_bjdata create a JSON value from an input in BJData format
  • to_cbor create a CBOR serialization of a JSON value
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value

Version history

  • Added in version 3.11.0.
  • BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
\ No newline at end of file +

See also

  • from_bjdata create a JSON value from an input in BJData format
  • to_cbor create a CBOR serialization of a JSON value
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value

Version history

  • Added in version 3.11.0.
  • BJData version parameter (for draft3 binary encoding) added in version 3.12.0.
\ No newline at end of file diff --git a/api/basic_json/to_bjdata/index.md b/api/basic_json/to_bjdata/index.md new file mode 100644 index 000000000..318355719 --- /dev/null +++ b/api/basic_json/to_bjdata/index.md @@ -0,0 +1,144 @@ +# nlohmann::basic_json::to_bjdata + +``` +// (1) +static std::vector to_bjdata(const basic_json& j, + const bool use_size = false, + const bool use_type = false, + const bjdata_version_t version = bjdata_version_t::draft2); + +// (2) +static void to_bjdata(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false, + const bjdata_version_t version = bjdata_version_t::draft2); +static void to_bjdata(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false, + const bjdata_version_t version = bjdata_version_t::draft2); +``` + +Serializes a given JSON value `j` to a byte vector using the BJData (Binary JData) serialization format. BJData aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the BJData serialization. +1. Writes the BJData serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/bjdata/index.md). + +## Parameters + +`j` (in) : JSON value to serialize + +`o` (in) : output adapter to write serialization to + +`use_size` (in) : whether to add size annotations to container types; optional, `false` by default. + +`use_type` (in) : whether to add type annotations to container types (must be combined with `use_size = true`); optional, `false` by default. + +`version` (in) : which version of BJData to use (see note on "Binary values" on [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md)); optional, `bjdata_version_t::draft2` by default. + +## Return value + +1. BJData serialization as byte vector +1. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +Example + +The example shows the serialization of a JSON value to a byte vector in BJData format. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +// function to print BJData's diagnostic format +void print_byte(uint8_t byte) +{ + if (32 < byte and byte < 128) + { + std::cout << (char)byte; + } + else + { + std::cout << (int)byte; + } +} + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": false})"_json; + + // serialize it to BJData + std::vector v = json::to_bjdata(j); + + // print the vector content + for (auto& byte : v) + { + print_byte(byte); + } + std::cout << std::endl; + + // create an array of numbers + json array = {1, 2, 3, 4, 5, 6, 7, 8}; + + // serialize it to BJData using default representation + std::vector v_array = json::to_bjdata(array); + // serialize it to BJData using size optimization + std::vector v_array_size = json::to_bjdata(array, true); + // serialize it to BJData using type optimization + std::vector v_array_size_and_type = json::to_bjdata(array, true, true); + + // print the vector contents + for (auto& byte : v_array) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size_and_type) + { + print_byte(byte); + } + std::cout << std::endl; +} +``` + +Output: + +``` +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 +``` + +## See also + +- [from_bjdata](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md) create a JSON value from an input in BJData format +- [to_cbor](https://json.nlohmann.me/api/basic_json/to_cbor/index.md) create a CBOR serialization of a JSON value +- [to_msgpack](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) create a MessagePack serialization of a JSON value +- [to_bson](https://json.nlohmann.me/api/basic_json/to_bson/index.md) create a BSON serialization of a JSON value +- [to_ubjson](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) create a UBJSON serialization of a JSON value + +## Version history + +- Added in version 3.11.0. +- BJData version parameter (for draft3 binary encoding) added in version 3.12.0. diff --git a/api/basic_json/to_bson.md b/api/basic_json/to_bson.md new file mode 100644 index 000000000..cb199dc32 --- /dev/null +++ b/api/basic_json/to_bson.md @@ -0,0 +1,74 @@ +# nlohmann::basic_json::to_bson + +```cpp +// (1) +static std::vector to_bson(const basic_json& j); + +// (2) +static void to_bson(const basic_json& j, detail::output_adapter o); +static void to_bson(const basic_json& j, detail::output_adapter o); +``` + +BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are stored as a single entity (a +so-called document). + +1. Returns a byte vector containing the BSON serialization. +2. Writes the BSON serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/bson.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +## Return value + +1. BSON serialization as a byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`type_error.317`](../../home/exceptions.md#jsonexceptiontype_error317) if the top-level type of the JSON value + is not an object; example: `"to serialize to BSON, top-level type must be object, but is string"` +- Throws [`out_of_range.409`](../../home/exceptions.md#jsonexceptionout_of_range409) if a key in the JSON object contains + a null byte (code point U+0000); example: `"BSON key cannot contain code point U+0000 (at byte 2)"` + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in BSON format. + + ```cpp + --8<-- "examples/to_bson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_bson.output" + ``` + +## See also + +- [from_bson](from_bson.md) create a JSON value from an input in BSON format +- [to_cbor](to_cbor.md) create a CBOR serialization of a JSON value +- [to_msgpack](to_msgpack.md) create a MessagePack serialization of a JSON value +- [to_ubjson](to_ubjson.md) create a UBJSON serialization of a JSON value +- [to_bjdata](to_bjdata.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 3.4.0. diff --git a/api/basic_json/to_bson/index.html b/api/basic_json/to_bson/index.html index 5818ea9df..71ef973e3 100644 --- a/api/basic_json/to_bson/index.html +++ b/api/basic_json/to_bson/index.html @@ -27,4 +27,4 @@ std::cout << std::endl; }

Output:

0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 
-

See also

  • from_bson create a JSON value from an input in BSON format
  • to_cbor create a CBOR serialization of a JSON value
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 3.4.0.
\ No newline at end of file +

See also

  • from_bson create a JSON value from an input in BSON format
  • to_cbor create a CBOR serialization of a JSON value
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 3.4.0.
\ No newline at end of file diff --git a/api/basic_json/to_bson/index.md b/api/basic_json/to_bson/index.md new file mode 100644 index 000000000..f95fa313f --- /dev/null +++ b/api/basic_json/to_bson/index.md @@ -0,0 +1,90 @@ +# nlohmann::basic_json::to_bson + +``` +// (1) +static std::vector to_bson(const basic_json& j); + +// (2) +static void to_bson(const basic_json& j, detail::output_adapter o); +static void to_bson(const basic_json& j, detail::output_adapter o); +``` + +BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are stored as a single entity (a so-called document). + +1. Returns a byte vector containing the BSON serialization. +1. Writes the BSON serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/bson/index.md). + +## Parameters + +`j` (in) : JSON value to serialize + +`o` (in) : output adapter to write serialization to + +## Return value + +1. BSON serialization as a byte vector +1. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Exceptions + +- Throws [`type_error.317`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error317) if the top-level type of the JSON value is not an object; example: `"to serialize to BSON, top-level type must be object, but is string"` +- Throws [`out_of_range.409`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range409) if a key in the JSON object contains a null byte (code point U+0000); example: `"BSON key cannot contain code point U+0000 (at byte 2)"` + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +Example + +The example shows the serialization of a JSON value to a byte vector in BSON format. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to BSON + std::vector v = json::to_bson(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} +``` + +Output: + +``` +0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 +``` + +## See also + +- [from_bson](https://json.nlohmann.me/api/basic_json/from_bson/index.md) create a JSON value from an input in BSON format +- [to_cbor](https://json.nlohmann.me/api/basic_json/to_cbor/index.md) create a CBOR serialization of a JSON value +- [to_msgpack](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) create a MessagePack serialization of a JSON value +- [to_ubjson](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) create a UBJSON serialization of a JSON value +- [to_bjdata](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 3.4.0. diff --git a/api/basic_json/to_cbor.md b/api/basic_json/to_cbor.md new file mode 100644 index 000000000..93facfca0 --- /dev/null +++ b/api/basic_json/to_cbor.md @@ -0,0 +1,69 @@ +# nlohmann::basic_json::to_cbor + +```cpp +// (1) +static std::vector to_cbor(const basic_json& j); + +// (2) +static void to_cbor(const basic_json& j, detail::output_adapter o); +static void to_cbor(const basic_json& j, detail::output_adapter o); +``` + +Serializes a given JSON value `j` to a byte vector using the CBOR (Concise Binary Object Representation) serialization +format. CBOR is a binary serialization format that aims to be more compact than JSON itself, yet more efficient to +parse. + +1. Returns a byte vector containing the CBOR serialization. +2. Writes the CBOR serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/cbor.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +## Return value + +1. CBOR serialization as a byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in CBOR format. + + ```cpp + --8<-- "examples/to_cbor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_cbor.output" + ``` + +## See also + +- [from_cbor](from_cbor.md) create a JSON value from an input in CBOR format +- [to_msgpack](to_msgpack.md) create a MessagePack serialization of a JSON value +- [to_bson](to_bson.md) create a BSON serialization of a JSON value +- [to_ubjson](to_ubjson.md) create a UBJSON serialization of a JSON value +- [to_bjdata](to_bjdata.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 2.0.9. +- Compact representation of floating-point numbers added in version 3.8.0. diff --git a/api/basic_json/to_cbor/index.html b/api/basic_json/to_cbor/index.html index 5cf4742f8..a9d1fbe75 100644 --- a/api/basic_json/to_cbor/index.html +++ b/api/basic_json/to_cbor/index.html @@ -27,4 +27,4 @@ std::cout << std::endl; }

Output:

0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 
-

See also

  • from_cbor create a JSON value from an input in CBOR format
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 2.0.9.
  • Compact representation of floating-point numbers added in version 3.8.0.
\ No newline at end of file +

See also

  • from_cbor create a JSON value from an input in CBOR format
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 2.0.9.
  • Compact representation of floating-point numbers added in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/to_cbor/index.md b/api/basic_json/to_cbor/index.md new file mode 100644 index 000000000..6f4973df5 --- /dev/null +++ b/api/basic_json/to_cbor/index.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::to_cbor + +``` +// (1) +static std::vector to_cbor(const basic_json& j); + +// (2) +static void to_cbor(const basic_json& j, detail::output_adapter o); +static void to_cbor(const basic_json& j, detail::output_adapter o); +``` + +Serializes a given JSON value `j` to a byte vector using the CBOR (Concise Binary Object Representation) serialization format. CBOR is a binary serialization format that aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the CBOR serialization. +1. Writes the CBOR serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/cbor/index.md). + +## Parameters + +`j` (in) : JSON value to serialize + +`o` (in) : output adapter to write serialization to + +## Return value + +1. CBOR serialization as a byte vector +1. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +Example + +The example shows the serialization of a JSON value to a byte vector in CBOR format. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to CBOR + std::vector v = json::to_cbor(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} +``` + +Output: + +``` +0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 +``` + +## See also + +- [from_cbor](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) create a JSON value from an input in CBOR format +- [to_msgpack](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) create a MessagePack serialization of a JSON value +- [to_bson](https://json.nlohmann.me/api/basic_json/to_bson/index.md) create a BSON serialization of a JSON value +- [to_ubjson](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) create a UBJSON serialization of a JSON value +- [to_bjdata](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 2.0.9. +- Compact representation of floating-point numbers added in version 3.8.0. diff --git a/api/basic_json/to_msgpack.md b/api/basic_json/to_msgpack.md new file mode 100644 index 000000000..66b104f52 --- /dev/null +++ b/api/basic_json/to_msgpack.md @@ -0,0 +1,67 @@ +# nlohmann::basic_json::to_msgpack + +```cpp +// (1) +static std::vector to_msgpack(const basic_json& j); + +// (2) +static void to_msgpack(const basic_json& j, detail::output_adapter o); +static void to_msgpack(const basic_json& j, detail::output_adapter o); +``` + +Serializes a given JSON value `j` to a byte vector using the MessagePack serialization format. MessagePack is a binary +serialization format that aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the MessagePack serialization. +2. Writes the MessagePack serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/messagepack.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +## Return value + +1. MessagePack serialization as a byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in MessagePack format. + + ```cpp + --8<-- "examples/to_msgpack.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_msgpack.output" + ``` + +## See also + +- [from_msgpack](from_msgpack.md) create a JSON value from an input in MessagePack format +- [to_cbor](to_cbor.md) create a CBOR serialization of a JSON value +- [to_bson](to_bson.md) create a BSON serialization of a JSON value +- [to_ubjson](to_ubjson.md) create a UBJSON serialization of a JSON value +- [to_bjdata](to_bjdata.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 2.0.9. diff --git a/api/basic_json/to_msgpack/index.html b/api/basic_json/to_msgpack/index.html index c76ac04d4..2e19c3572 100644 --- a/api/basic_json/to_msgpack/index.html +++ b/api/basic_json/to_msgpack/index.html @@ -27,4 +27,4 @@ std::cout << std::endl; }

Output:

0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 
-

See also

  • from_msgpack create a JSON value from an input in MessagePack format
  • to_cbor create a CBOR serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 2.0.9.
\ No newline at end of file +

See also

  • from_msgpack create a JSON value from an input in MessagePack format
  • to_cbor create a CBOR serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_ubjson create a UBJSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 2.0.9.
\ No newline at end of file diff --git a/api/basic_json/to_msgpack/index.md b/api/basic_json/to_msgpack/index.md new file mode 100644 index 000000000..95a88179a --- /dev/null +++ b/api/basic_json/to_msgpack/index.md @@ -0,0 +1,85 @@ +# nlohmann::basic_json::to_msgpack + +``` +// (1) +static std::vector to_msgpack(const basic_json& j); + +// (2) +static void to_msgpack(const basic_json& j, detail::output_adapter o); +static void to_msgpack(const basic_json& j, detail::output_adapter o); +``` + +Serializes a given JSON value `j` to a byte vector using the MessagePack serialization format. MessagePack is a binary serialization format that aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the MessagePack serialization. +1. Writes the MessagePack serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/messagepack/index.md). + +## Parameters + +`j` (in) : JSON value to serialize + +`o` (in) : output adapter to write serialization to + +## Return value + +1. MessagePack serialization as a byte vector +1. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +Example + +The example shows the serialization of a JSON value to a byte vector in MessagePack format. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to MessagePack + std::vector v = json::to_msgpack(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} +``` + +Output: + +``` +0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 +``` + +## See also + +- [from_msgpack](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md) create a JSON value from an input in MessagePack format +- [to_cbor](https://json.nlohmann.me/api/basic_json/to_cbor/index.md) create a CBOR serialization of a JSON value +- [to_bson](https://json.nlohmann.me/api/basic_json/to_bson/index.md) create a BSON serialization of a JSON value +- [to_ubjson](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) create a UBJSON serialization of a JSON value +- [to_bjdata](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 2.0.9. diff --git a/api/basic_json/to_string.md b/api/basic_json/to_string.md new file mode 100644 index 000000000..2df16c132 --- /dev/null +++ b/api/basic_json/to_string.md @@ -0,0 +1,66 @@ +# to_string(basic_json) + +```cpp +template +std::string to_string(const BasicJsonType& j); +``` + +This function implements a user-defined to_string for JSON objects. + +## Template parameters + +`BasicJsonType` +: a specialization of [`basic_json`](index.md) + +## Return value + +string containing the serialization of the JSON value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value +is not UTF-8 encoded + +## Complexity + +Linear. + +## Possible implementation + +```cpp +template +std::string to_string(const BasicJsonType& j) +{ + return j.dump(); +} +``` + +## Examples + +??? example + + The following code shows how the library's `to_string()` function integrates with others, allowing + argument-dependent lookup. + + ```cpp + --8<-- "examples/to_string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_string.output" + ``` + +## See also + +- [dump](dump.md) +- [Serialization](../../features/serialization.md) - the serialization article + +## Version history + +Added in version 3.7.0. diff --git a/api/basic_json/to_string/index.html b/api/basic_json/to_string/index.html index c7b3fccc9..b4608f30b 100644 --- a/api/basic_json/to_string/index.html +++ b/api/basic_json/to_string/index.html @@ -28,4 +28,4 @@

Output:

{"one":1,"two":2}
 
 42
-

See also

Version history

Added in version 3.7.0.

\ No newline at end of file +

See also

Version history

Added in version 3.7.0.

\ No newline at end of file diff --git a/api/basic_json/to_string/index.md b/api/basic_json/to_string/index.md new file mode 100644 index 000000000..ca581bc1e --- /dev/null +++ b/api/basic_json/to_string/index.md @@ -0,0 +1,84 @@ +# to_string(basic_json) + +``` +template +std::string to_string(const BasicJsonType& j); +``` + +This function implements a user-defined to_string for JSON objects. + +## Template parameters + +`BasicJsonType` : a specialization of [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) + +## Return value + +string containing the serialization of the JSON value + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +Throws [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) if a string stored inside the JSON value is not UTF-8 encoded + +## Complexity + +Linear. + +## Possible implementation + +``` +template +std::string to_string(const BasicJsonType& j) +{ + return j.dump(); +} +``` + +## Examples + +Example + +The following code shows how the library's `to_string()` function integrates with others, allowing argument-dependent lookup. + +``` +#include +#include + +using json = nlohmann::json; +using std::to_string; + +int main() +{ + // create values + json j = {{"one", 1}, {"two", 2}}; + int i = 42; + + // use ADL to select best to_string function + auto j_str = to_string(j); // calling nlohmann::to_string + auto i_str = to_string(i); // calling std::to_string + + // serialize without indentation + std::cout << j_str << "\n\n" + << i_str << std::endl; +} +``` + +Output: + +``` +{"one":1,"two":2} + +42 +``` + +## See also + +- [dump](https://json.nlohmann.me/api/basic_json/dump/index.md) +- [Serialization](https://json.nlohmann.me/features/serialization/index.md) - the serialization article + +## Version history + +Added in version 3.7.0. diff --git a/api/basic_json/to_ubjson.md b/api/basic_json/to_ubjson.md new file mode 100644 index 000000000..39b184e74 --- /dev/null +++ b/api/basic_json/to_ubjson.md @@ -0,0 +1,78 @@ +# nlohmann::basic_json::to_ubjson + +```cpp +// (1) +static std::vector to_ubjson(const basic_json& j, + const bool use_size = false, + const bool use_type = false); + +// (2) +static void to_ubjson(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +static void to_ubjson(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +``` + +Serializes a given JSON value `j` to a byte vector using the UBJSON (Universal Binary JSON) serialization format. UBJSON +aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the UBJSON serialization. +2. Writes the UBJSON serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](../../features/binary_formats/ubjson.md). + +## Parameters + +`j` (in) +: JSON value to serialize + +`o` (in) +: output adapter to write serialization to + +`use_size` (in) +: whether to add size annotations to container types; optional, `#!cpp false` by default. + +`use_type` (in) +: whether to add type annotations to container types (must be combined with `#!cpp use_size = true`); optional, + `#!cpp false` by default. + +## Return value + +1. UBJSON serialization as a byte vector +2. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +??? example + + The example shows the serialization of a JSON value to a byte vector in UBJSON format. + + ```cpp + --8<-- "examples/to_ubjson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/to_ubjson.output" + ``` + +## See also + +- [from_ubjson](from_ubjson.md) create a JSON value from an input in UBJSON format +- [to_cbor](to_cbor.md) create a CBOR serialization of a JSON value +- [to_msgpack](to_msgpack.md) create a MessagePack serialization of a JSON value +- [to_bson](to_bson.md) create a BSON serialization of a JSON value +- [to_bjdata](to_bjdata.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 3.1.0. diff --git a/api/basic_json/to_ubjson/index.html b/api/basic_json/to_ubjson/index.html index 6338679dc..38df7491c 100644 --- a/api/basic_json/to_ubjson/index.html +++ b/api/basic_json/to_ubjson/index.html @@ -76,4 +76,4 @@ [i1i2i3i4i5i6i7i8] [#i8i1i2i3i4i5i6i7i8 [$i#i812345678 -

See also

  • from_ubjson create a JSON value from an input in UBJSON format
  • to_cbor create a CBOR serialization of a JSON value
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 3.1.0.
\ No newline at end of file +

See also

  • from_ubjson create a JSON value from an input in UBJSON format
  • to_cbor create a CBOR serialization of a JSON value
  • to_msgpack create a MessagePack serialization of a JSON value
  • to_bson create a BSON serialization of a JSON value
  • to_bjdata create a BJData serialization of a JSON value

Version history

  • Added in version 3.1.0.
\ No newline at end of file diff --git a/api/basic_json/to_ubjson/index.md b/api/basic_json/to_ubjson/index.md new file mode 100644 index 000000000..e9afb0b6c --- /dev/null +++ b/api/basic_json/to_ubjson/index.md @@ -0,0 +1,138 @@ +# nlohmann::basic_json::to_ubjson + +``` +// (1) +static std::vector to_ubjson(const basic_json& j, + const bool use_size = false, + const bool use_type = false); + +// (2) +static void to_ubjson(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +static void to_ubjson(const basic_json& j, detail::output_adapter o, + const bool use_size = false, const bool use_type = false); +``` + +Serializes a given JSON value `j` to a byte vector using the UBJSON (Universal Binary JSON) serialization format. UBJSON aims to be more compact than JSON itself, yet more efficient to parse. + +1. Returns a byte vector containing the UBJSON serialization. +1. Writes the UBJSON serialization to an output adapter. + +The exact mapping and its limitations are described on a [dedicated page](https://json.nlohmann.me/features/binary_formats/ubjson/index.md). + +## Parameters + +`j` (in) : JSON value to serialize + +`o` (in) : output adapter to write serialization to + +`use_size` (in) : whether to add size annotations to container types; optional, `false` by default. + +`use_type` (in) : whether to add type annotations to container types (must be combined with `use_size = true`); optional, `false` by default. + +## Return value + +1. UBJSON serialization as a byte vector +1. (none) + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes in the JSON value. + +## Complexity + +Linear in the size of the JSON value `j`. + +## Examples + +Example + +The example shows the serialization of a JSON value to a byte vector in UBJSON format. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +// function to print UBJSON's diagnostic format +void print_byte(uint8_t byte) +{ + if (32 < byte and byte < 128) + { + std::cout << (char)byte; + } + else + { + std::cout << (int)byte; + } +} + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": false})"_json; + + // serialize it to UBJSON + std::vector v = json::to_ubjson(j); + + // print the vector content + for (auto& byte : v) + { + print_byte(byte); + } + std::cout << std::endl; + + // create an array of numbers + json array = {1, 2, 3, 4, 5, 6, 7, 8}; + + // serialize it to UBJSON using default representation + std::vector v_array = json::to_ubjson(array); + // serialize it to UBJSON using size optimization + std::vector v_array_size = json::to_ubjson(array, true); + // serialize it to UBJSON using type optimization + std::vector v_array_size_and_type = json::to_ubjson(array, true, true); + + // print the vector contents + for (auto& byte : v_array) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size_and_type) + { + print_byte(byte); + } + std::cout << std::endl; +} +``` + +Output: + +``` +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 +``` + +## See also + +- [from_ubjson](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md) create a JSON value from an input in UBJSON format +- [to_cbor](https://json.nlohmann.me/api/basic_json/to_cbor/index.md) create a CBOR serialization of a JSON value +- [to_msgpack](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) create a MessagePack serialization of a JSON value +- [to_bson](https://json.nlohmann.me/api/basic_json/to_bson/index.md) create a BSON serialization of a JSON value +- [to_bjdata](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) create a BJData serialization of a JSON value + +## Version history + +- Added in version 3.1.0. diff --git a/api/basic_json/type.md b/api/basic_json/type.md new file mode 100644 index 000000000..deedd6b69 --- /dev/null +++ b/api/basic_json/type.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::type + +```cpp +constexpr value_t type() const noexcept; +``` + +Return the type of the JSON value as a value from the [`value_t`](value_t.md) enumeration. + +## Return value + +the type of the JSON value + +| Value type | return value | +|---------------------------|----------------------------| +| `#!json null` | `value_t::null` | +| boolean | `value_t::boolean` | +| string | `value_t::string` | +| number (integer) | `value_t::number_integer` | +| number (unsigned integer) | `value_t::number_unsigned` | +| number (floating-point) | `value_t::number_float` | +| object | `value_t::object` | +| array | `value_t::array` | +| binary | `value_t::binary` | +| discarded | `value_t::discarded` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `type()` for all JSON types. + + ```cpp + --8<-- "examples/type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/api/basic_json/type/index.html b/api/basic_json/type/index.html index aa84e26fd..2667bbd1c 100644 --- a/api/basic_json/type/index.html +++ b/api/basic_json/type/index.html @@ -35,4 +35,4 @@ true true true -

Version history

  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/type/index.md b/api/basic_json/type/index.md new file mode 100644 index 000000000..a5af678fc --- /dev/null +++ b/api/basic_json/type/index.md @@ -0,0 +1,88 @@ +# nlohmann::basic_json::type + +``` +constexpr value_t type() const noexcept; +``` + +Return the type of the JSON value as a value from the [`value_t`](https://json.nlohmann.me/api/basic_json/value_t/index.md) enumeration. + +## Return value + +the type of the JSON value + +| Value type | return value | +| ------------------------- | -------------------------- | +| `null` | `value_t::null` | +| boolean | `value_t::boolean` | +| string | `value_t::string` | +| number (integer) | `value_t::number_integer` | +| number (unsigned integer) | `value_t::number_unsigned` | +| number (floating-point) | `value_t::number_float` | +| object | `value_t::object` | +| array | `value_t::array` | +| binary | `value_t::binary` | +| discarded | `value_t::discarded` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `type()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = -17; + json j_number_unsigned = 42u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call type() + std::cout << std::boolalpha; + std::cout << (j_null.type() == json::value_t::null) << '\n'; + std::cout << (j_boolean.type() == json::value_t::boolean) << '\n'; + std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\n'; + std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\n'; + std::cout << (j_number_float.type() == json::value_t::number_float) << '\n'; + std::cout << (j_object.type() == json::value_t::object) << '\n'; + std::cout << (j_array.type() == json::value_t::array) << '\n'; + std::cout << (j_string.type() == json::value_t::string) << '\n'; +} +``` + +Output: + +``` +true +true +true +true +true +true +true +true +``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/api/basic_json/type_error.md b/api/basic_json/type_error.md new file mode 100644 index 000000000..b13fdd278 --- /dev/null +++ b/api/basic_json/type_error.md @@ -0,0 +1,79 @@ +# nlohmann::basic_json::type_error + +```cpp +class type_error : public exception; +``` + +This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type +does not match the expected semantics. + +Exceptions have ids 3xx (see [list of type errors](../../home/exceptions.md#type-errors)). + +```mermaid +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_type_error fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +??? example + + The following code shows how a `type_error` exception can be caught. + + ```cpp + --8<-- "examples/type_error.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type_error.output" + ``` + +## See also + +- [`exception`](exception.md) for the base class of all exceptions thrown by the library +- [List of type errors](../../home/exceptions.md#type-errors) +- [`parse_error`](parse_error.md) for exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators +- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`other_error`](other_error.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/type_error/index.html b/api/basic_json/type_error/index.html index 8d67964a6..448363130 100644 --- a/api/basic_json/type_error/index.html +++ b/api/basic_json/type_error/index.html @@ -49,4 +49,4 @@ }

Output:

message: [json.exception.type_error.308] cannot use push_back() with string
 exception id: 308
-

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file +

See also

Version history

  • Since version 3.0.0.
\ No newline at end of file diff --git a/api/basic_json/type_error/index.md b/api/basic_json/type_error/index.md new file mode 100644 index 000000000..131d314e0 --- /dev/null +++ b/api/basic_json/type_error/index.md @@ -0,0 +1,98 @@ +# nlohmann::basic_json::type_error + +``` +class type_error : public exception; +``` + +This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics. + +Exceptions have ids 3xx (see [list of type errors](https://json.nlohmann.me/home/exceptions/#type-errors)). + +``` +classDiagram + direction LR + + class std_exception ["std::exception"] { + <> + } + + class json_exception ["basic_json::exception"] { + +const int id + +const char* what() const + } + + class json_parse_error ["basic_json::parse_error"] { + +const std::size_t byte + } + + class json_invalid_iterator ["basic_json::invalid_iterator"] + class json_type_error ["basic_json::type_error"] + class json_out_of_range ["basic_json::out_of_range"] + class json_other_error ["basic_json::other_error"] + + std_exception <|-- json_exception + json_exception <|-- json_parse_error + json_exception <|-- json_invalid_iterator + json_exception <|-- json_type_error + json_exception <|-- json_out_of_range + json_exception <|-- json_other_error + + style json_type_error fill:#CCCCFF +``` + +## Member functions + +- **what** - returns explanatory string + +## Member variables + +- **id** - the id of the exception + +## Examples + +Example + +The following code shows how a `type_error` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling push_back() on a string value + json j = "string"; + j.push_back("another string"); + } + catch (const json::type_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.type_error.308] cannot use push_back() with string +exception id: 308 +``` + +## See also + +- [`exception`](https://json.nlohmann.me/api/basic_json/exception/index.md) for the base class of all exceptions thrown by the library +- [List of type errors](https://json.nlohmann.me/home/exceptions/#type-errors) +- [`parse_error`](https://json.nlohmann.me/api/basic_json/parse_error/index.md) for exceptions indicating a parse error +- [`invalid_iterator`](https://json.nlohmann.me/api/basic_json/invalid_iterator/index.md) for exceptions indicating errors with iterators +- [`out_of_range`](https://json.nlohmann.me/api/basic_json/out_of_range/index.md) for exceptions indicating access out of the defined range +- [`other_error`](https://json.nlohmann.me/api/basic_json/other_error/index.md) for exceptions indicating other library errors + +## Version history + +- Since version 3.0.0. diff --git a/api/basic_json/type_name.md b/api/basic_json/type_name.md new file mode 100644 index 000000000..389c2b1dd --- /dev/null +++ b/api/basic_json/type_name.md @@ -0,0 +1,54 @@ +# nlohmann::basic_json::type_name + +```cpp +const char* type_name() const noexcept; +``` + +Returns the type name as string to be used in error messages -- usually to indicate that a function was called on a +wrong JSON type. + +## Return value + +a string representation of the type ([`value_t`](value_t.md)): + +| Value type | return value | +|----------------------------------------------------|---------------| +| `#!json null` | `"null"` | +| boolean | `"boolean"` | +| string | `"string"` | +| number (integer, unsigned integer, floating-point) | `"number"` | +| object | `"object"` | +| array | `"array"` | +| binary | `"binary"` | +| discarded | `"discarded"` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The following code exemplifies `type_name()` for all JSON types. + + ```cpp + --8<-- "examples/type_name.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type_name.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Part of the public API version since 2.1.0. +- Changed return value to `const char*` and added `noexcept` in version 3.0.0. +- Added support for binary type in version 3.8.0. diff --git a/api/basic_json/type_name/index.html b/api/basic_json/type_name/index.html index 5635583d4..960e11dfe 100644 --- a/api/basic_json/type_name/index.html +++ b/api/basic_json/type_name/index.html @@ -34,4 +34,4 @@ {"one":1,"two":2} is an object [1,2,4,8,16] is an array "Hello, world" is a string -

Version history

  • Added in version 1.0.0.
  • Part of the public API version since 2.1.0.
  • Changed return value to const char* and added noexcept in version 3.0.0.
  • Added support for binary type in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
  • Part of the public API version since 2.1.0.
  • Changed return value to const char* and added noexcept in version 3.0.0.
  • Added support for binary type in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/type_name/index.md b/api/basic_json/type_name/index.md new file mode 100644 index 000000000..7b1007356 --- /dev/null +++ b/api/basic_json/type_name/index.md @@ -0,0 +1,86 @@ +# nlohmann::basic_json::type_name + +``` +const char* type_name() const noexcept; +``` + +Returns the type name as string to be used in error messages -- usually to indicate that a function was called on a wrong JSON type. + +## Return value + +a string representation of the type ([`value_t`](https://json.nlohmann.me/api/basic_json/value_t/index.md)): + +| Value type | return value | +| -------------------------------------------------- | ------------- | +| `null` | `"null"` | +| boolean | `"boolean"` | +| string | `"string"` | +| number (integer, unsigned integer, floating-point) | `"number"` | +| object | `"object"` | +| array | `"array"` | +| binary | `"binary"` | +| discarded | `"discarded"` | + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The following code exemplifies `type_name()` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = -17; + json j_number_unsigned = 42u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call type_name() + std::cout << j_null << " is a " << j_null.type_name() << '\n'; + std::cout << j_boolean << " is a " << j_boolean.type_name() << '\n'; + std::cout << j_number_integer << " is a " << j_number_integer.type_name() << '\n'; + std::cout << j_number_unsigned << " is a " << j_number_unsigned.type_name() << '\n'; + std::cout << j_number_float << " is a " << j_number_float.type_name() << '\n'; + std::cout << j_object << " is an " << j_object.type_name() << '\n'; + std::cout << j_array << " is an " << j_array.type_name() << '\n'; + std::cout << j_string << " is a " << j_string.type_name() << '\n'; +} +``` + +Output: + +``` +null is a null +true is a boolean +-17 is a number +42 is a number +23.42 is a number +{"one":1,"two":2} is an object +[1,2,4,8,16] is an array +"Hello, world" is a string +``` + +## Version history + +- Added in version 1.0.0. +- Part of the public API version since 2.1.0. +- Changed return value to `const char*` and added `noexcept` in version 3.0.0. +- Added support for binary type in version 3.8.0. diff --git a/api/basic_json/unflatten.md b/api/basic_json/unflatten.md new file mode 100644 index 000000000..1af243b58 --- /dev/null +++ b/api/basic_json/unflatten.md @@ -0,0 +1,65 @@ +# nlohmann::basic_json::unflatten + +```cpp +basic_json unflatten() const; +``` + +The function restores the arbitrary nesting of a JSON value that has been flattened before using the +[`flatten()`](flatten.md) function. The JSON value must meet certain constraints: + +1. The value must be an object. +2. The keys must be JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901)) +3. The mapped values must be primitive JSON types. + +## Return value + +the original JSON from a flattened version + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +The function can throw the following exceptions: + +- Throws [`type_error.314`](../../home/exceptions.md#jsonexceptiontype_error314) if value is not an object +- Throws [`type_error.315`](../../home/exceptions.md#jsonexceptiontype_error315) if object values are not primitive +- Throws [`type_error.313`](../../home/exceptions.md#jsonexceptiontype_error313) if a key (JSON pointer) leads to a + conflicting nesting; example: `"invalid value to unflatten"` +- Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a key is not a + number; example: `"array index 'one' is not a number"` + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +Empty objects and arrays are flattened by [`flatten()`](flatten.md) to `#!json null` values and cannot unflattened to +their original type. Apart from this example, for a JSON value `j`, the following is always true: +`#!cpp j == j.flatten().unflatten()`. + +## Examples + +??? example + + The following code shows how a flattened JSON object is unflattened into the original nested JSON object. + + ```cpp + --8<-- "examples/unflatten.cpp" + ``` + + Output: + + ```json + --8<-- "examples/unflatten.output" + ``` + +## See also + +- [flatten](flatten.md) the reverse function + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/unflatten/index.html b/api/basic_json/unflatten/index.html index 53f1d0030..bb59624ce 100644 --- a/api/basic_json/unflatten/index.html +++ b/api/basic_json/unflatten/index.html @@ -43,4 +43,4 @@ }, "pi": 3.141 } -

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file +

See also

Version history

  • Added in version 2.0.0.
\ No newline at end of file diff --git a/api/basic_json/unflatten/index.md b/api/basic_json/unflatten/index.md new file mode 100644 index 000000000..fee3fed56 --- /dev/null +++ b/api/basic_json/unflatten/index.md @@ -0,0 +1,102 @@ +# nlohmann::basic_json::unflatten + +``` +basic_json unflatten() const; +``` + +The function restores the arbitrary nesting of a JSON value that has been flattened before using the [`flatten()`](https://json.nlohmann.me/api/basic_json/flatten/index.md) function. The JSON value must meet certain constraints: + +1. The value must be an object. +1. The keys must be JSON pointers (see [RFC 6901](https://tools.ietf.org/html/rfc6901)) +1. The mapped values must be primitive JSON types. + +## Return value + +the original JSON from a flattened version + +## Exception safety + +Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +The function can throw the following exceptions: + +- Throws [`type_error.314`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error314) if value is not an object +- Throws [`type_error.315`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error315) if object values are not primitive +- Throws [`type_error.313`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error313) if a key (JSON pointer) leads to a conflicting nesting; example: `"invalid value to unflatten"` +- Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) if an array index in a key is not a number; example: `"array index 'one' is not a number"` + +## Complexity + +Linear in the size of the JSON value. + +## Notes + +Empty objects and arrays are flattened by [`flatten()`](https://json.nlohmann.me/api/basic_json/flatten/index.md) to `null` values and cannot unflattened to their original type. Apart from this example, for a JSON value `j`, the following is always true: `j == j.flatten().unflatten()`. + +## Examples + +Example + +The following code shows how a flattened JSON object is unflattened into the original nested JSON object. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON value + json j_flattened = + { + {"/answer/everything", 42}, + {"/happy", true}, + {"/list/0", 1}, + {"/list/1", 0}, + {"/list/2", 2}, + {"/name", "Niels"}, + {"/nothing", nullptr}, + {"/object/currency", "USD"}, + {"/object/value", 42.99}, + {"/pi", 3.141} + }; + + // call unflatten() + std::cout << std::setw(4) << j_flattened.unflatten() << '\n'; +} +``` + +Output: + +``` +{ + "answer": { + "everything": 42 + }, + "happy": true, + "list": [ + 1, + 0, + 2 + ], + "name": "Niels", + "nothing": null, + "object": { + "currency": "USD", + "value": 42.99 + }, + "pi": 3.141 +} +``` + +## See also + +- [flatten](https://json.nlohmann.me/api/basic_json/flatten/index.md) the reverse function + +## Version history + +- Added in version 2.0.0. diff --git a/api/basic_json/update.md b/api/basic_json/update.md new file mode 100644 index 000000000..b34140dbc --- /dev/null +++ b/api/basic_json/update.md @@ -0,0 +1,157 @@ +# nlohmann::basic_json::update + +```cpp +// (1) +void update(const_reference j, bool merge_objects = false); + +// (2) +void update(const_iterator first, const_iterator last, bool merge_objects = false); +``` + +1. Inserts all values from JSON object `j`. +2. Inserts all values from range `[first, last)` + +When `merge_objects` is `#!c false` (default), existing keys are overwritten. When `merge_objects` is `#!c true`, +recursively merges objects with common keys. + +If the JSON value is `#!json null`, it is implicitly converted to an empty object before the values are inserted. + +The function is motivated by Python's [dict.update](https://docs.python.org/3.6/library/stdtypes.html#dict.update) +function. + +## Iterator invalidation + +For [`ordered_json`](../ordered_json.md), adding a value to an object can yield a reallocation, in which case all +iterators (including the `end()` iterator) and all references to the elements are invalidated. + +## Parameters + +`j` (in) +: JSON object to read values from + +`merge_objects` (in) +: when `#!c true`, keys that exist in both objects and whose value in the source is itself an object are merged + recursively; all other values are overwritten as usual (default: `#!c false`) + +`first` (in) +: the beginning of the range of elements to insert + +`last` (in) +: the end of the range of elements to insert + +## Exception safety + +Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.312`](../../home/exceptions.md#jsonexceptiontype_error312) if called on JSON values other than + objects; example: `"cannot use update() with string"` +2. The function can throw the following exceptions: + - Throws [`type_error.312`](../../home/exceptions.md#jsonexceptiontype_error312) if called on JSON values other than + objects; example: `"cannot use update() with string"` + - Throws [`invalid_iterator.210`](../../home/exceptions.md#jsonexceptioninvalid_iterator210) if `first` and `last` + do not belong to the same JSON value; example: `"iterators do not fit"` + +## Complexity + +1. O(N*log(size() + N)), where N is the number of elements to insert. +2. O(N*log(size() + N)), where N is the number of elements to insert. + +## Examples + +??? example + + The example shows how `update()` is used. + + ```cpp + --8<-- "examples/update.cpp" + ``` + + Output: + + ```json + --8<-- "examples/update.output" + ``` + +??? example + + The example shows how `update()` is used. + + ```cpp + --8<-- "examples/update__range.cpp" + ``` + + Output: + + ```json + --8<-- "examples/update__range.output" + ``` + +??? example + + One common use case for this function is the handling of user settings. Assume your application can be configured in + some aspects: + + ```json + { + "color": "red", + "active": true, + "name": {"de": "Maus", "en": "mouse"} + } + ``` + + The user may override the default settings selectively: + + ```json + { + "color": "blue", + "name": {"es": "ratón"}, + } + ``` + + Then `update` manages the merging of default settings and user settings: + + ```cpp + auto user_settings = json::parse("config.json"); + auto effective_settings = get_default_settings(); + effective_settings.update(user_settings); + ``` + + Now `effective_settings` contains the default settings, but those keys set by the user are overwritten: + + ```json + { + "color": "blue", + "active": true, + "name": {"es": "ratón"} + } + ``` + + Note existing keys were just overwritten. To merge objects, `merge_objects` setting should be set to `#!c true`: + + ```cpp + auto user_settings = json::parse("config.json"); + auto effective_settings = get_default_settings(); + effective_settings.update(user_settings, true); + ``` + + ```json + { + "color": "blue", + "active": true, + "name": {"de": "Maus", "en": "mouse", "es": "ratón"} + } + ``` + +## See also + +- [insert](insert.md) add values to an array/object +- [merge_patch](merge_patch.md) applies a JSON Merge Patch +- [Modifying values](../../features/modifying_values.md) - the article on modifying values + +## Version history + +- Added in version 3.0.0. +- Added `merge_objects` parameter in 3.10.5. diff --git a/api/basic_json/update/index.html b/api/basic_json/update/index.html index 33b4d84d3..e39e97f85 100644 --- a/api/basic_json/update/index.html +++ b/api/basic_json/update/index.html @@ -110,4 +110,4 @@ "active": true, "name": {"de": "Maus", "en": "mouse", "es": "ratón"} } -

See also

Version history

  • Added in version 3.0.0.
  • Added merge_objects parameter in 3.10.5.
\ No newline at end of file +

See also

Version history

  • Added in version 3.0.0.
  • Added merge_objects parameter in 3.10.5.
\ No newline at end of file diff --git a/api/basic_json/update/index.md b/api/basic_json/update/index.md new file mode 100644 index 000000000..127a4deab --- /dev/null +++ b/api/basic_json/update/index.md @@ -0,0 +1,223 @@ +# nlohmann::basic_json::update + +``` +// (1) +void update(const_reference j, bool merge_objects = false); + +// (2) +void update(const_iterator first, const_iterator last, bool merge_objects = false); +``` + +1. Inserts all values from JSON object `j`. +1. Inserts all values from range `[first, last)` + +When `merge_objects` is `false` (default), existing keys are overwritten. When `merge_objects` is `true`, recursively merges objects with common keys. + +If the JSON value is `null`, it is implicitly converted to an empty object before the values are inserted. + +The function is motivated by Python's [dict.update](https://docs.python.org/3.6/library/stdtypes.html#dict.update) function. + +## Iterator invalidation + +For [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), adding a value to an object can yield a reallocation, in which case all iterators (including the `end()` iterator) and all references to the elements are invalidated. + +## Parameters + +`j` (in) : JSON object to read values from + +`merge_objects` (in) : when `true`, keys that exist in both objects and whose value in the source is itself an object are merged recursively; all other values are overwritten as usual (default: `false`) + +`first` (in) : the beginning of the range of elements to insert + +`last` (in) : the end of the range of elements to insert + +## Exception safety + +Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.312`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error312) if called on JSON values other than objects; example: `"cannot use update() with string"` +1. The function can throw the following exceptions: + - Throws [`type_error.312`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error312) if called on JSON values other than objects; example: `"cannot use update() with string"` + - Throws [`invalid_iterator.210`](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator210) if `first` and `last` do not belong to the same JSON value; example: `"iterators do not fit"` + +## Complexity + +1. O(N\*log(size() + N)), where N is the number of elements to insert. +1. O(N\*log(size() + N)), where N is the number of elements to insert. + +## Examples + +Example + +The example shows how `update()` is used. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create two JSON objects + json o1 = R"( {"color": "red", "price": 17.99, "names": {"de": "Flugzeug"}} )"_json; + json o2 = R"( {"color": "blue", "speed": 100, "names": {"en": "plane"}} )"_json; + json o3 = o1; + + // add all keys from o2 to o1 (updating "color", replacing "names") + o1.update(o2); + + // add all keys from o2 to o1 (updating "color", merging "names") + o3.update(o2, true); + + // output updated object o1 and o3 + std::cout << std::setw(2) << o1 << '\n'; + std::cout << std::setw(2) << o3 << '\n'; +} +``` + +Output: + +``` +{ + "color": "blue", + "names": { + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +{ + "color": "blue", + "names": { + "de": "Flugzeug", + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +``` + +Example + +The example shows how `update()` is used. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create two JSON objects + json o1 = R"( {"color": "red", "price": 17.99, "names": {"de": "Flugzeug"}} )"_json; + json o2 = R"( {"color": "blue", "speed": 100, "names": {"en": "plane"}} )"_json; + json o3 = o1; + + // add all keys from o2 to o1 (updating "color", replacing "names") + o1.update(o2.begin(), o2.end()); + + // add all keys from o2 to o1 (updating "color", merging "names") + o3.update(o2.begin(), o2.end(), true); + + // output updated object o1 and o3 + std::cout << std::setw(2) << o1 << '\n'; + std::cout << std::setw(2) << o3 << '\n'; +} +``` + +Output: + +``` +{ + "color": "blue", + "names": { + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +{ + "color": "blue", + "names": { + "de": "Flugzeug", + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +``` + +Example + +One common use case for this function is the handling of user settings. Assume your application can be configured in some aspects: + +``` +{ + "color": "red", + "active": true, + "name": {"de": "Maus", "en": "mouse"} +} +``` + +The user may override the default settings selectively: + +``` +{ + "color": "blue", + "name": {"es": "ratón"}, +} +``` + +Then `update` manages the merging of default settings and user settings: + +``` +auto user_settings = json::parse("config.json"); +auto effective_settings = get_default_settings(); +effective_settings.update(user_settings); +``` + +Now `effective_settings` contains the default settings, but those keys set by the user are overwritten: + +``` +{ + "color": "blue", + "active": true, + "name": {"es": "ratón"} +} +``` + +Note existing keys were just overwritten. To merge objects, `merge_objects` setting should be set to `true`: + +``` +auto user_settings = json::parse("config.json"); +auto effective_settings = get_default_settings(); +effective_settings.update(user_settings, true); +``` + +``` +{ + "color": "blue", + "active": true, + "name": {"de": "Maus", "en": "mouse", "es": "ratón"} +} +``` + +## See also + +- [insert](https://json.nlohmann.me/api/basic_json/insert/index.md) add values to an array/object +- [merge_patch](https://json.nlohmann.me/api/basic_json/merge_patch/index.md) applies a JSON Merge Patch +- [Modifying values](https://json.nlohmann.me/features/modifying_values/index.md) - the article on modifying values + +## Version history + +- Added in version 3.0.0. +- Added `merge_objects` parameter in 3.10.5. diff --git a/api/basic_json/value.md b/api/basic_json/value.md new file mode 100644 index 000000000..7d1cac8cf --- /dev/null +++ b/api/basic_json/value.md @@ -0,0 +1,187 @@ +# nlohmann::basic_json::value + +```cpp +// (1) +template +ValueType value(const typename object_t::key_type& key, + ValueType&& default_value) const; + +// (2) +template +ValueType value(KeyType&& key, + ValueType&& default_value) const; + +// (3) +template +ValueType value(const json_pointer& ptr, + const ValueType& default_value) const; +``` + +1. Returns either a copy of an object's element at the specified key `key` or a given default value if no element with + key `key` exists. + + The function is basically equivalent to executing + ```cpp + try { + return at(key); + } catch(out_of_range) { + return default_value; + } + ``` + +2. See 1. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and + `#!cpp typename object_comparator_t::is_transparent` denotes a type. + +3. Returns either a copy of an object's element at the specified JSON pointer `ptr` or a given default value if no value + at `ptr` exists. + + The function is basically equivalent to executing + ```cpp + try { + return at(ptr); + } catch(out_of_range) { + return default_value; + } + ``` + +!!! note "Differences to `at` and `operator[]`" + + - Unlike [`at`](at.md), this function does not throw if the given `key`/`ptr` was not found. + - Unlike [`operator[]`](operator[].md), this function does not implicitly add an element to the position defined by + `key`/`ptr` key. This function is furthermore also applicable to const objects. + +## Template parameters + +`KeyType` +: A type for an object key other than [`json_pointer`](../json_pointer/index.md) that is comparable with + [`string_t`](string_t.md) using [`object_comparator_t`](object_comparator_t.md). + This can also be a string view (C++17). +`ValueType` +: type compatible to JSON values, for instance `#!cpp int` for JSON integer numbers, `#!cpp bool` for JSON booleans, + or `#!cpp std::vector` types for JSON arrays. Note the type of the expected value at `key`/`ptr` and the default + value `default_value` must be compatible. + +## Parameters + +`key` (in) +: key of the element to access + +`default_value` (in) +: the value to return if `key`/`ptr` found no value + +`ptr` (in) +: a JSON pointer to the element to access + +## Return value + +1. copy of the element at key `key` or `default_value` if `key` is not found +2. copy of the element at key `key` or `default_value` if `key` is not found +3. copy of the element at JSON Pointer `ptr` or `default_value` if no value for `ptr` is found + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no +changes to any JSON value. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `default_value` does not match + the type of the value at `key` + - Throws [`type_error.306`](../../home/exceptions.md#jsonexceptiontype_error306) if the JSON value is not an object; + in that case, using `value()` with a key makes no sense. +2. See 1. +3. The function can throw the following exceptions: + - Throws [`type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) if `default_value` does not match + the type of the value at `ptr` + - Throws [`type_error.306`](../../home/exceptions.md#jsonexceptiontype_error306) if the JSON value is not an array + or object; in that case, using `value()` with a JSON pointer makes no sense. + - Throws [`parse_error.106`](../../home/exceptions.md#jsonexceptionparse_error106) if an array index in the passed + JSON pointer `ptr` begins with '0'. + - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in the passed + JSON pointer `ptr` is not a number. + +## Complexity + +1. Logarithmic in the size of the container. +2. Logarithmic in the size of the container. +3. Logarithmic in the size of the container. + +## Notes + +!!! warning "Return type" + + The value function is a template, and the return type of the function is determined by the type of the provided + default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit + unsigned integer. We get exactly that value when using [`operator[]`](operator[].md). However, when we call `value` + and provide `#!c 0` as default value, then `#!c -1` is returned. This occurs, because `#!c 0` has type `#!c int` + which overflows when handling the value `#!c 18446744073709551615`. + + To address this issue, either provide a correctly typed default value or use the template parameter to specify the + desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default + value is not used as the return value. + + ```cpp + --8<-- "examples/value__return_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__return_type.output" + ``` + +## Examples + +??? example "Example: (1) access specified object element with default value" + + The example below shows how object elements can be queried with a default value. + + ```cpp + --8<-- "examples/value__object_t_key_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__object_t_key_type.output" + ``` + +??? example "Example: (2) access specified object element using string_view with default value" + + The example below shows how object elements can be queried with a default value. + + ```cpp + --8<-- "examples/value__keytype.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__keytype.c++17.output" + ``` + +??? example "Example: (3) access specified object element via JSON Pointer with default value" + + The example below shows how object elements can be queried with a default value. + + ```cpp + --8<-- "examples/value__json_ptr.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__json_ptr.output" + ``` + +## See also + +- see [`at`](at.md) for access by reference with range checking +- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference + +## Version history + +1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version 3.11.0. +2. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2. +3. Added in version 2.0.2. Extended to work with arrays in version 3.12.x. diff --git a/api/basic_json/value/index.html b/api/basic_json/value/index.html index 7b82d1b17..76a97ccdc 100644 --- a/api/basic_json/value/index.html +++ b/api/basic_json/value/index.html @@ -136,4 +136,4 @@ << " " << v_string << " " << v_boolean << "\n"; }

Output:

1 42.23 oops false
-

See also

  • see at for access by reference with range checking
  • see operator[] for unchecked access by reference

Version history

  1. Added in version 1.0.0. Changed parameter default_value type from const ValueType& to ValueType&& in version 3.11.0.
  2. Added in version 3.11.0. Made ValueType the first template parameter in version 3.11.2.
  3. Added in version 2.0.2. Extended to work with arrays in version 3.12.x.
\ No newline at end of file +

See also

  • see at for access by reference with range checking
  • see operator[] for unchecked access by reference

Version history

  1. Added in version 1.0.0. Changed parameter default_value type from const ValueType& to ValueType&& in version 3.11.0.
  2. Added in version 3.11.0. Made ValueType the first template parameter in version 3.11.2.
  3. Added in version 2.0.2. Extended to work with arrays in version 3.12.x.
\ No newline at end of file diff --git a/api/basic_json/value/index.md b/api/basic_json/value/index.md new file mode 100644 index 000000000..0e76a3322 --- /dev/null +++ b/api/basic_json/value/index.md @@ -0,0 +1,270 @@ +# nlohmann::basic_json::value + +``` +// (1) +template +ValueType value(const typename object_t::key_type& key, + ValueType&& default_value) const; + +// (2) +template +ValueType value(KeyType&& key, + ValueType&& default_value) const; + +// (3) +template +ValueType value(const json_pointer& ptr, + const ValueType& default_value) const; +``` + +1. Returns either a copy of an object's element at the specified key `key` or a given default value if no element with key `key` exists. + + The function is basically equivalent to executing + + ``` + try { + return at(key); + } catch(out_of_range) { + return default_value; + } + ``` + +1. See 1. This overload is only available if `KeyType` is comparable with `typename object_t::key_type` and `typename object_comparator_t::is_transparent` denotes a type. + +1. Returns either a copy of an object's element at the specified JSON pointer `ptr` or a given default value if no value at `ptr` exists. + + The function is basically equivalent to executing + + ``` + try { + return at(ptr); + } catch(out_of_range) { + return default_value; + } + ``` + +Differences to `at` and `operator[]` + +- Unlike [`at`](https://json.nlohmann.me/api/basic_json/at/index.md), this function does not throw if the given `key`/`ptr` was not found. +- Unlike [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md), this function does not implicitly add an element to the position defined by `key`/`ptr` key. This function is furthermore also applicable to const objects. + +## Template parameters + +`KeyType` : A type for an object key other than [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) that is comparable with [`string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) using [`object_comparator_t`](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md). This can also be a string view (C++17). + +`ValueType` : type compatible to JSON values, for instance `int` for JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for JSON arrays. Note the type of the expected value at `key`/`ptr` and the default value `default_value` must be compatible. + +## Parameters + +`key` (in) : key of the element to access + +`default_value` (in) : the value to return if `key`/`ptr` found no value + +`ptr` (in) : a JSON pointer to the element to access + +## Return value + +1. copy of the element at key `key` or `default_value` if `key` is not found +1. copy of the element at key `key` or `default_value` if `key` is not found +1. copy of the element at JSON Pointer `ptr` or `default_value` if no value for `ptr` is found + +## Exception safety + +Strong guarantee: if an exception is thrown, there are no changes to any JSON value. + +## Exceptions + +1. The function can throw the following exceptions: + - Throws [`type_error.302`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error302) if `default_value` does not match the type of the value at `key` + - Throws [`type_error.306`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error306) if the JSON value is not an object; in that case, using `value()` with a key makes no sense. +1. See 1. +1. The function can throw the following exceptions: + - Throws [`type_error.302`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error302) if `default_value` does not match the type of the value at `ptr` + - Throws [`type_error.306`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error306) if the JSON value is not an array or object; in that case, using `value()` with a JSON pointer makes no sense. + - Throws [`parse_error.106`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error106) if an array index in the passed JSON pointer `ptr` begins with '0'. + - Throws [`parse_error.109`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error109) if an array index in the passed JSON pointer `ptr` is not a number. + +## Complexity + +1. Logarithmic in the size of the container. +1. Logarithmic in the size of the container. +1. Logarithmic in the size of the container. + +## Notes + +Return type + +The value function is a template, and the return type of the function is determined by the type of the provided default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit unsigned integer. We get exactly that value when using [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md). However, when we call `value` and provide `0` as default value, then `-1` is returned. This occurs, because `0` has type `int` which overflows when handling the value `18446744073709551615`. + +To address this issue, either provide a correctly typed default value or use the template parameter to specify the desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default value is not used as the return value. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j = json::parse(R"({"uint64": 18446744073709551615})"); + + std::cout << "operator[]: " << j["uint64"] << '\n' + << "default value (int): " << j.value("uint64", 0) << '\n' + << "default value (uint64_t): " << j.value("uint64", std::uint64_t(0)) << '\n' + << "explicit return value type: " << j.value("uint64", 0) << '\n'; +} +``` + +Output: + +``` +operator[]: 18446744073709551615 +default value (int): -1 +default value (uint64_t): 18446744073709551615 +explicit return value type: 18446744073709551615 +``` + +## Examples + +Example: (1) access specified object element with default value + +The example below shows how object elements can be queried with a default value. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object with different entry types + json j = + { + {"integer", 1}, + {"floating", 42.23}, + {"string", "hello world"}, + {"boolean", true}, + {"object", {{"key1", 1}, {"key2", 2}}}, + {"array", {1, 2, 3}} + }; + + // access existing values + int v_integer = j.value("integer", 0); + double v_floating = j.value("floating", 47.11); + + // access nonexisting values and rely on default value + std::string v_string = j.value("nonexisting", "oops"); + bool v_boolean = j.value("nonexisting", false); + + // output values + std::cout << std::boolalpha << v_integer << " " << v_floating + << " " << v_string << " " << v_boolean << "\n"; +} +``` + +Output: + +``` +1 42.23 oops false +``` + +Example: (2) access specified object element using string_view with default value + +The example below shows how object elements can be queried with a default value. + +``` +#include +#include +#include + +using namespace std::string_view_literals; +using json = nlohmann::json; + +int main() +{ + // create a JSON object with different entry types + json j = + { + {"integer", 1}, + {"floating", 42.23}, + {"string", "hello world"}, + {"boolean", true}, + {"object", {{"key1", 1}, {"key2", 2}}}, + {"array", {1, 2, 3}} + }; + + // access existing values + int v_integer = j.value("integer"sv, 0); + double v_floating = j.value("floating"sv, 47.11); + + // access nonexisting values and rely on default value + std::string v_string = j.value("nonexisting"sv, "oops"); + bool v_boolean = j.value("nonexisting"sv, false); + + // output values + std::cout << std::boolalpha << v_integer << " " << v_floating + << " " << v_string << " " << v_boolean << "\n"; +} +``` + +Output: + +``` +1 42.23 oops false +``` + +Example: (3) access specified object element via JSON Pointer with default value + +The example below shows how object elements can be queried with a default value. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON object with different entry types + json j = + { + {"integer", 1}, + {"floating", 42.23}, + {"string", "hello world"}, + {"boolean", true}, + {"object", {{"key1", 1}, {"key2", 2}}}, + {"array", {1, 2, 3}} + }; + + // access existing values + int v_integer = j.value("/integer"_json_pointer, 0); + double v_floating = j.value("/floating"_json_pointer, 47.11); + + // access nonexisting values and rely on default value + std::string v_string = j.value("/nonexisting"_json_pointer, "oops"); + bool v_boolean = j.value("/nonexisting"_json_pointer, false); + + // output values + std::cout << std::boolalpha << v_integer << " " << v_floating + << " " << v_string << " " << v_boolean << "\n"; +} +``` + +Output: + +``` +1 42.23 oops false +``` + +## See also + +- see [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) for access by reference with range checking +- see [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) for unchecked access by reference + +## Version history + +1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version 3.11.0. +1. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2. +1. Added in version 2.0.2. Extended to work with arrays in version 3.12.x. diff --git a/api/basic_json/value_t.md b/api/basic_json/value_t.md new file mode 100644 index 000000000..1505e02d0 --- /dev/null +++ b/api/basic_json/value_t.md @@ -0,0 +1,81 @@ +# nlohmann::basic_json::value_t + +```cpp +enum class value_t : std::uint8_t { + null, + object, + array, + string, + boolean, + number_integer, + number_unsigned, + number_float, + binary, + discarded +}; +``` + +This enumeration collects the different JSON types. It is internally used to distinguish the stored values, and the +functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_array.md), [`is_string`](is_string.md), +[`is_boolean`](is_boolean.md), [`is_number`](is_number.md) (with [`is_number_integer`](is_number_integer.md), +[`is_number_unsigned`](is_number_unsigned.md), and [`is_number_float`](is_number_float.md)), +[`is_discarded`](is_discarded.md), [`is_binary`](is_binary.md), [`is_primitive`](is_primitive.md), and +[`is_structured`](is_structured.md) rely on it. + +## Notes + +!!! note "Ordering" + + The order of types is as follows: + + 1. `null` + 2. `boolean` + 3. `number_integer`, `number_unsigned`, `number_float` + 4. `object` + 5. `array` + 6. `string` + 7. `binary` + + `discarded` is unordered. + +!!! note "Types of numbers" + + There are three enumerators for numbers (`number_integer`, `number_unsigned`, and `number_float`) to distinguish + between different types of numbers: + + - [`number_unsigned_t`](number_unsigned_t.md) for unsigned integers + - [`number_integer_t`](number_integer_t.md) for signed integers + - [`number_float_t`](number_float_t.md) for floating-point numbers or to approximate integers which do not fit + into the limits of their respective type + +!!! warning "Comparison operators" + + `operator<` and `operator<=>` (since C++20) are overloaded and compare according to the ordering described above. + Until C++20 all other relational and equality operators yield results according to the integer value of each + enumerator. Since C++20 some compilers consider the _rewritten candidates_ generated from `operator<=>` during + overload resolution, while others do not. For predictable and portable behavior use: + + - `operator<` or `operator<=>` when wanting to compare according to the order described above + - `operator==` or `operator!=` when wanting to compare according to each enumerators integer value + +## Examples + +??? example + + The following code how `type()` queries the `value_t` for all JSON types. + + ```cpp + --8<-- "examples/type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/type.output" + ``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/api/basic_json/value_t/index.html b/api/basic_json/value_t/index.html index 803995a4f..2dfb23a39 100644 --- a/api/basic_json/value_t/index.html +++ b/api/basic_json/value_t/index.html @@ -46,4 +46,4 @@ true true true -

Version history

  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 1.0.0.
  • Added unsigned integer type in version 2.0.0.
  • Added binary type in version 3.8.0.
\ No newline at end of file diff --git a/api/basic_json/value_t/index.md b/api/basic_json/value_t/index.md new file mode 100644 index 000000000..81978a9b1 --- /dev/null +++ b/api/basic_json/value_t/index.md @@ -0,0 +1,105 @@ +# nlohmann::basic_json::value_t + +``` +enum class value_t : std::uint8_t { + null, + object, + array, + string, + boolean, + number_integer, + number_unsigned, + number_float, + binary, + discarded +}; +``` + +This enumeration collects the different JSON types. It is internally used to distinguish the stored values, and the functions [`is_null`](https://json.nlohmann.me/api/basic_json/is_null/index.md), [`is_object`](https://json.nlohmann.me/api/basic_json/is_object/index.md), [`is_array`](https://json.nlohmann.me/api/basic_json/is_array/index.md), [`is_string`](https://json.nlohmann.me/api/basic_json/is_string/index.md), [`is_boolean`](https://json.nlohmann.me/api/basic_json/is_boolean/index.md), [`is_number`](https://json.nlohmann.me/api/basic_json/is_number/index.md) (with [`is_number_integer`](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md), [`is_number_unsigned`](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md), and [`is_number_float`](https://json.nlohmann.me/api/basic_json/is_number_float/index.md)), [`is_discarded`](https://json.nlohmann.me/api/basic_json/is_discarded/index.md), [`is_binary`](https://json.nlohmann.me/api/basic_json/is_binary/index.md), [`is_primitive`](https://json.nlohmann.me/api/basic_json/is_primitive/index.md), and [`is_structured`](https://json.nlohmann.me/api/basic_json/is_structured/index.md) rely on it. + +## Notes + +Ordering + +The order of types is as follows: + +1. `null` +1. `boolean` +1. `number_integer`, `number_unsigned`, `number_float` +1. `object` +1. `array` +1. `string` +1. `binary` + +`discarded` is unordered. + +Types of numbers + +There are three enumerators for numbers (`number_integer`, `number_unsigned`, and `number_float`) to distinguish between different types of numbers: + +- [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) for unsigned integers +- [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) for signed integers +- [`number_float_t`](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) for floating-point numbers or to approximate integers which do not fit into the limits of their respective type + +Comparison operators + +`operator<` and `operator<=>` (since C++20) are overloaded and compare according to the ordering described above. Until C++20 all other relational and equality operators yield results according to the integer value of each enumerator. Since C++20 some compilers consider the *rewritten candidates* generated from `operator<=>` during overload resolution, while others do not. For predictable and portable behavior use: + +- `operator<` or `operator<=>` when wanting to compare according to the order described above +- `operator==` or `operator!=` when wanting to compare according to each enumerators integer value + +## Examples + +Example + +The following code how `type()` queries the `value_t` for all JSON types. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_null; + json j_boolean = true; + json j_number_integer = -17; + json j_number_unsigned = 42u; + json j_number_float = 23.42; + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hello, world"; + + // call type() + std::cout << std::boolalpha; + std::cout << (j_null.type() == json::value_t::null) << '\n'; + std::cout << (j_boolean.type() == json::value_t::boolean) << '\n'; + std::cout << (j_number_integer.type() == json::value_t::number_integer) << '\n'; + std::cout << (j_number_unsigned.type() == json::value_t::number_unsigned) << '\n'; + std::cout << (j_number_float.type() == json::value_t::number_float) << '\n'; + std::cout << (j_object.type() == json::value_t::object) << '\n'; + std::cout << (j_array.type() == json::value_t::array) << '\n'; + std::cout << (j_string.type() == json::value_t::string) << '\n'; +} +``` + +Output: + +``` +true +true +true +true +true +true +true +true +``` + +## Version history + +- Added in version 1.0.0. +- Added unsigned integer type in version 2.0.0. +- Added binary type in version 3.8.0. diff --git a/api/basic_json/~basic_json.md b/api/basic_json/~basic_json.md new file mode 100644 index 000000000..64e944006 --- /dev/null +++ b/api/basic_json/~basic_json.md @@ -0,0 +1,21 @@ +# nlohmann::basic_json::~basic_json + +```cpp +~basic_json() noexcept; +``` + +Destroys the JSON value and frees all allocated memory. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Linear. + + + +## Version history + +- Added in version 1.0.0. diff --git a/api/basic_json/~basic_json/index.html b/api/basic_json/~basic_json/index.html index 63e9bf52d..dfc0b4e77 100644 --- a/api/basic_json/~basic_json/index.html +++ b/api/basic_json/~basic_json/index.html @@ -1,2 +1,2 @@ (Destructor) - JSON for Modern C++

nlohmann::basic_json::~basic_json

~basic_json() noexcept;
-

Destroys the JSON value and frees all allocated memory.

Exception safety

No-throw guarantee: this member function never throws exceptions.

Complexity

Linear.

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

Destroys the JSON value and frees all allocated memory.

Exception safety

No-throw guarantee: this member function never throws exceptions.

Complexity

Linear.

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/basic_json/~basic_json/index.md b/api/basic_json/~basic_json/index.md new file mode 100644 index 000000000..2c3740924 --- /dev/null +++ b/api/basic_json/~basic_json/index.md @@ -0,0 +1,19 @@ +# nlohmann::basic_json::~basic_json + +``` +~basic_json() noexcept; +``` + +Destroys the JSON value and frees all allocated memory. + +## Exception safety + +No-throw guarantee: this member function never throws exceptions. + +## Complexity + +Linear. + +## Version history + +- Added in version 1.0.0. diff --git a/api/byte_container_with_subtype.md b/api/byte_container_with_subtype.md new file mode 100644 index 000000000..a9aafc1d2 --- /dev/null +++ b/api/byte_container_with_subtype.md @@ -0,0 +1,35 @@ +# nlohmann::byte_container_with_subtype + +```cpp +template +class byte_container_with_subtype : public BinaryType; +``` + +This type extends the template parameter `BinaryType` provided to [`basic_json`](../basic_json/index.md) with a subtype +used by BSON and MessagePack. This type exists so that the user does not have to specify a type themselves with a +specific naming scheme in order to override the binary type. + +## Template parameters + +`BinaryType` +: container to store bytes (`#!cpp std::vector` by default) + +## Member types + +- **container_type** - the type of the underlying container (`BinaryType`) +- **subtype_type** - the type of the subtype (`#!cpp std::uint64_t`) + +## Member functions + +- [(constructor)](byte_container_with_subtype.md) +- **operator==** - comparison: equal +- **operator!=** - comparison: not equal +- [**set_subtype**](set_subtype.md) - sets the binary subtype +- [**subtype**](subtype.md) - return the binary subtype +- [**has_subtype**](has_subtype.md) - return whether the value has a subtype +- [**clear_subtype**](clear_subtype.md) - clears the binary subtype + +## Version history + +- Added in version 3.8.0. +- Changed the type of subtypes to `#!cpp std::uint64_t` in 3.10.0. diff --git a/api/byte_container_with_subtype/byte_container_with_subtype.md b/api/byte_container_with_subtype/byte_container_with_subtype.md new file mode 100644 index 000000000..c8e47cfa3 --- /dev/null +++ b/api/byte_container_with_subtype/byte_container_with_subtype.md @@ -0,0 +1,46 @@ +# nlohmann::byte_container_with_subtype::byte_container_with_subtype + +```cpp +// (1) +byte_container_with_subtype(); + +// (2) +byte_container_with_subtype(const container_type& container); +byte_container_with_subtype(container_type&& container); + +// (3) +byte_container_with_subtype(const container_type& container, subtype_type subtype); +byte_container_with_subtype(container_type&& container, subtype_type subtype); +``` + +1. Create an empty binary container without a subtype. +2. Create a binary container without a subtype. +3. Create a binary container with a subtype. + +## Parameters + +`container` (in) +: binary container + +`subtype` (in) +: subtype + +## Examples + +??? example + + The example below demonstrates how byte containers can be created. + + ```cpp + --8<-- "examples/byte_container_with_subtype__byte_container_with_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__byte_container_with_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/byte_container_with_subtype/index.html b/api/byte_container_with_subtype/byte_container_with_subtype/index.html index 8648f1921..16225b10e 100644 --- a/api/byte_container_with_subtype/byte_container_with_subtype/index.html +++ b/api/byte_container_with_subtype/byte_container_with_subtype/index.html @@ -34,4 +34,4 @@

Output:

{"bytes":[],"subtype":null}
 {"bytes":[202,254,186,190],"subtype":null}
 {"bytes":[202,254,186,190],"subtype":42}
-

Version history

Since version 3.8.0.

\ No newline at end of file +

Version history

Since version 3.8.0.

\ No newline at end of file diff --git a/api/byte_container_with_subtype/byte_container_with_subtype/index.md b/api/byte_container_with_subtype/byte_container_with_subtype/index.md new file mode 100644 index 000000000..5df4a89fe --- /dev/null +++ b/api/byte_container_with_subtype/byte_container_with_subtype/index.md @@ -0,0 +1,68 @@ +# nlohmann::byte_container_with_subtype::byte_container_with_subtype + +``` +// (1) +byte_container_with_subtype(); + +// (2) +byte_container_with_subtype(const container_type& container); +byte_container_with_subtype(container_type&& container); + +// (3) +byte_container_with_subtype(const container_type& container, subtype_type subtype); +byte_container_with_subtype(container_type&& container, subtype_type subtype); +``` + +1. Create an empty binary container without a subtype. +1. Create a binary container without a subtype. +1. Create a binary container with a subtype. + +## Parameters + +`container` (in) : binary container + +`subtype` (in) : subtype + +## Examples + +Example + +The example below demonstrates how byte containers can be created. + +``` +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +using json = nlohmann::json; + +int main() +{ + // (1) create empty container + auto c1 = byte_container_with_subtype(); + + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // (2) create container + auto c2 = byte_container_with_subtype(bytes); + + // (3) create container with subtype + auto c3 = byte_container_with_subtype(bytes, 42); + + std::cout << json(c1) << "\n" << json(c2) << "\n" << json(c3) << std::endl; +} +``` + +Output: + +``` +{"bytes":[],"subtype":null} +{"bytes":[202,254,186,190],"subtype":null} +{"bytes":[202,254,186,190],"subtype":42} +``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/clear_subtype.md b/api/byte_container_with_subtype/clear_subtype.md new file mode 100644 index 000000000..f4bb891ee --- /dev/null +++ b/api/byte_container_with_subtype/clear_subtype.md @@ -0,0 +1,36 @@ +# nlohmann::byte_container_with_subtype::clear_subtype + +```cpp +void clear_subtype() noexcept; +``` + +Clears the binary subtype and flags the value as not having a subtype, which has implications for serialization; for +instance, MessagePack will prefer the bin family over the ext family. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how `clear_subtype` can remove subtypes. + + ```cpp + --8<-- "examples/byte_container_with_subtype__clear_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__clear_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/clear_subtype/index.html b/api/byte_container_with_subtype/clear_subtype/index.html index 51afa92d2..b7484c54c 100644 --- a/api/byte_container_with_subtype/clear_subtype/index.html +++ b/api/byte_container_with_subtype/clear_subtype/index.html @@ -22,4 +22,4 @@ }

Output:

before calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":42}
 after calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":null}
-

Version history

Since version 3.8.0.

\ No newline at end of file +

Version history

Since version 3.8.0.

\ No newline at end of file diff --git a/api/byte_container_with_subtype/clear_subtype/index.md b/api/byte_container_with_subtype/clear_subtype/index.md new file mode 100644 index 000000000..04232137c --- /dev/null +++ b/api/byte_container_with_subtype/clear_subtype/index.md @@ -0,0 +1,56 @@ +# nlohmann::byte_container_with_subtype::clear_subtype + +``` +void clear_subtype() noexcept; +``` + +Clears the binary subtype and flags the value as not having a subtype, which has implications for serialization; for instance, MessagePack will prefer the bin family over the ext family. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The example below demonstrates how `clear_subtype` can remove subtypes. + +``` +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +using json = nlohmann::json; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container with subtype + auto c1 = byte_container_with_subtype(bytes, 42); + + std::cout << "before calling clear_subtype(): " << json(c1) << '\n'; + + c1.clear_subtype(); + + std::cout << "after calling clear_subtype(): " << json(c1) << '\n'; +} +``` + +Output: + +``` +before calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":42} +after calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":null} +``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/has_subtype.md b/api/byte_container_with_subtype/has_subtype.md new file mode 100644 index 000000000..e06286e29 --- /dev/null +++ b/api/byte_container_with_subtype/has_subtype.md @@ -0,0 +1,39 @@ +# nlohmann::byte_container_with_subtype::has_subtype + +```cpp +constexpr bool has_subtype() const noexcept; +``` + +Returns whether the value has a subtype. + +## Return value + +whether the value has a subtype + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how `has_subtype` can check whether a subtype was set. + + ```cpp + --8<-- "examples/byte_container_with_subtype__has_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__has_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/has_subtype/index.html b/api/byte_container_with_subtype/has_subtype/index.html index e6e341c26..f4716dd26 100644 --- a/api/byte_container_with_subtype/has_subtype/index.html +++ b/api/byte_container_with_subtype/has_subtype/index.html @@ -20,4 +20,4 @@ }

Output:

c1.has_subtype() = false
 c2.has_subtype() = true
-

Version history

Since version 3.8.0.

\ No newline at end of file +

Version history

Since version 3.8.0.

\ No newline at end of file diff --git a/api/byte_container_with_subtype/has_subtype/index.md b/api/byte_container_with_subtype/has_subtype/index.md new file mode 100644 index 000000000..e6164d3ab --- /dev/null +++ b/api/byte_container_with_subtype/has_subtype/index.md @@ -0,0 +1,58 @@ +# nlohmann::byte_container_with_subtype::has_subtype + +``` +constexpr bool has_subtype() const noexcept; +``` + +Returns whether the value has a subtype. + +## Return value + +whether the value has a subtype + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The example below demonstrates how `has_subtype` can check whether a subtype was set. + +``` +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container + auto c1 = byte_container_with_subtype(bytes); + + // create container with subtype + auto c2 = byte_container_with_subtype(bytes, 42); + + std::cout << std::boolalpha << "c1.has_subtype() = " << c1.has_subtype() + << "\nc2.has_subtype() = " << c2.has_subtype() << std::endl; +} +``` + +Output: + +``` +c1.has_subtype() = false +c2.has_subtype() = true +``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/index.html b/api/byte_container_with_subtype/index.html index e83768931..3b35d0d5b 100644 --- a/api/byte_container_with_subtype/index.html +++ b/api/byte_container_with_subtype/index.html @@ -1,3 +1,3 @@ Overview - JSON for Modern C++

nlohmann::byte_container_with_subtype

template<typename BinaryType>
 class byte_container_with_subtype : public BinaryType;
-

This type extends the template parameter BinaryType provided to basic_json with a subtype used by BSON and MessagePack. This type exists so that the user does not have to specify a type themselves with a specific naming scheme in order to override the binary type.

Template parameters

BinaryType
container to store bytes (std::vector<std::uint8_t> by default)

Member types

  • container_type - the type of the underlying container (BinaryType)
  • subtype_type - the type of the subtype (std::uint64_t)

Member functions

Version history

  • Added in version 3.8.0.
  • Changed the type of subtypes to std::uint64_t in 3.10.0.
\ No newline at end of file +

This type extends the template parameter BinaryType provided to basic_json with a subtype used by BSON and MessagePack. This type exists so that the user does not have to specify a type themselves with a specific naming scheme in order to override the binary type.

Template parameters

BinaryType
container to store bytes (std::vector<std::uint8_t> by default)

Member types

  • container_type - the type of the underlying container (BinaryType)
  • subtype_type - the type of the subtype (std::uint64_t)

Member functions

Version history

  • Added in version 3.8.0.
  • Changed the type of subtypes to std::uint64_t in 3.10.0.
\ No newline at end of file diff --git a/api/byte_container_with_subtype/index.md b/api/byte_container_with_subtype/index.md new file mode 100644 index 000000000..28e801a5c --- /dev/null +++ b/api/byte_container_with_subtype/index.md @@ -0,0 +1,32 @@ +# nlohmann::byte_container_with_subtype + +``` +template +class byte_container_with_subtype : public BinaryType; +``` + +This type extends the template parameter `BinaryType` provided to [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) with a subtype used by BSON and MessagePack. This type exists so that the user does not have to specify a type themselves with a specific naming scheme in order to override the binary type. + +## Template parameters + +`BinaryType` : container to store bytes (`std::vector` by default) + +## Member types + +- **container_type** - the type of the underlying container (`BinaryType`) +- **subtype_type** - the type of the subtype (`std::uint64_t`) + +## Member functions + +- [(constructor)](https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/index.md) +- **operator==** - comparison: equal +- **operator!=** - comparison: not equal +- [**set_subtype**](https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/index.md) - sets the binary subtype +- [**subtype**](https://json.nlohmann.me/api/byte_container_with_subtype/subtype/index.md) - return the binary subtype +- [**has_subtype**](https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/index.md) - return whether the value has a subtype +- [**clear_subtype**](https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/index.md) - clears the binary subtype + +## Version history + +- Added in version 3.8.0. +- Changed the type of subtypes to `std::uint64_t` in 3.10.0. diff --git a/api/byte_container_with_subtype/set_subtype.md b/api/byte_container_with_subtype/set_subtype.md new file mode 100644 index 000000000..cf21732b8 --- /dev/null +++ b/api/byte_container_with_subtype/set_subtype.md @@ -0,0 +1,41 @@ +# nlohmann::byte_container_with_subtype::set_subtype + +```cpp +void set_subtype(subtype_type subtype) noexcept; +``` + +Sets the binary subtype of the value, also flags a binary JSON value as having a subtype, which has implications for +serialization. + +## Parameters + +`subtype` (in) +: subtype to set + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how a subtype can be set with `set_subtype`. + + ```cpp + --8<-- "examples/byte_container_with_subtype__set_subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__set_subtype.output" + ``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/set_subtype/index.html b/api/byte_container_with_subtype/set_subtype/index.html index 4241acaca..972044c2b 100644 --- a/api/byte_container_with_subtype/set_subtype/index.html +++ b/api/byte_container_with_subtype/set_subtype/index.html @@ -23,4 +23,4 @@ }

Output:

before calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":null}
 after calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":42}
-

Version history

Since version 3.8.0.

\ No newline at end of file +

Version history

Since version 3.8.0.

\ No newline at end of file diff --git a/api/byte_container_with_subtype/set_subtype/index.md b/api/byte_container_with_subtype/set_subtype/index.md new file mode 100644 index 000000000..251d50147 --- /dev/null +++ b/api/byte_container_with_subtype/set_subtype/index.md @@ -0,0 +1,61 @@ +# nlohmann::byte_container_with_subtype::set_subtype + +``` +void set_subtype(subtype_type subtype) noexcept; +``` + +Sets the binary subtype of the value, also flags a binary JSON value as having a subtype, which has implications for serialization. + +## Parameters + +`subtype` (in) : subtype to set + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The example below demonstrates how a subtype can be set with `set_subtype`. + +``` +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +using json = nlohmann::json; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container without subtype + auto c = byte_container_with_subtype(bytes); + + std::cout << "before calling set_subtype(42): " << json(c) << '\n'; + + // set the subtype + c.set_subtype(42); + + std::cout << "after calling set_subtype(42): " << json(c) << '\n'; +} +``` + +Output: + +``` +before calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":null} +after calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":42} +``` + +## Version history + +Since version 3.8.0. diff --git a/api/byte_container_with_subtype/subtype.md b/api/byte_container_with_subtype/subtype.md new file mode 100644 index 000000000..389241a79 --- /dev/null +++ b/api/byte_container_with_subtype/subtype.md @@ -0,0 +1,42 @@ +# nlohmann::byte_container_with_subtype::subtype + +```cpp +constexpr subtype_type subtype() const noexcept; +``` + +Returns the numerical subtype of the value if it has a subtype. If it does not have a subtype, this function will return +`subtype_type(-1)` as a sentinel value. + +## Return value + +the numerical subtype of the binary value, or `subtype_type(-1)` if no subtype is set + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example below demonstrates how the subtype can be retrieved with `subtype`. Note how `subtype_type(-1)` is + returned for container `c1`. + + ```cpp + --8<-- "examples/byte_container_with_subtype__subtype.cpp" + ``` + + Output: + + ```json + --8<-- "examples/byte_container_with_subtype__subtype.output" + ``` + +## Version history + +- Added in version 3.8.0 +- Fixed return value to properly return `subtype_type(-1)` as documented in version 3.10.0. diff --git a/api/byte_container_with_subtype/subtype/index.html b/api/byte_container_with_subtype/subtype/index.html index 62c0d110e..1cc1bcd00 100644 --- a/api/byte_container_with_subtype/subtype/index.html +++ b/api/byte_container_with_subtype/subtype/index.html @@ -23,4 +23,4 @@ }

Output:

c1.subtype() = 18446744073709551615
 c2.subtype() = 42
-

Version history

  • Added in version 3.8.0
  • Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.
\ No newline at end of file +

Version history

  • Added in version 3.8.0
  • Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.
\ No newline at end of file diff --git a/api/byte_container_with_subtype/subtype/index.md b/api/byte_container_with_subtype/subtype/index.md new file mode 100644 index 000000000..9e8ea14de --- /dev/null +++ b/api/byte_container_with_subtype/subtype/index.md @@ -0,0 +1,62 @@ +# nlohmann::byte_container_with_subtype::subtype + +``` +constexpr subtype_type subtype() const noexcept; +``` + +Returns the numerical subtype of the value if it has a subtype. If it does not have a subtype, this function will return `subtype_type(-1)` as a sentinel value. + +## Return value + +the numerical subtype of the binary value, or `subtype_type(-1)` if no subtype is set + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The example below demonstrates how the subtype can be retrieved with `subtype`. Note how `subtype_type(-1)` is returned for container `c1`. + +``` +#include +#include + +// define a byte container based on std::vector +using byte_container_with_subtype = nlohmann::byte_container_with_subtype>; + +int main() +{ + std::vector bytes = {{0xca, 0xfe, 0xba, 0xbe}}; + + // create container + auto c1 = byte_container_with_subtype(bytes); + + // create container with subtype + auto c2 = byte_container_with_subtype(bytes, 42); + + std::cout << "c1.subtype() = " << c1.subtype() + << "\nc2.subtype() = " << c2.subtype() << std::endl; + + // in case no subtype is set, return special value + assert(c1.subtype() == static_cast(-1)); +} +``` + +Output: + +``` +c1.subtype() = 18446744073709551615 +c2.subtype() = 42 +``` + +## Version history + +- Added in version 3.8.0 +- Fixed return value to properly return `subtype_type(-1)` as documented in version 3.10.0. diff --git a/api/json.md b/api/json.md new file mode 100644 index 000000000..36edcc2c1 --- /dev/null +++ b/api/json.md @@ -0,0 +1,28 @@ +# nlohmann::json + +```cpp +using json = basic_json<>; +``` + +This type is the default specialization of the [basic_json](basic_json/index.md) class which uses the standard template +types. + +## Examples + +??? example + + The example below demonstrates how to use the type `nlohmann::json`. + + ```cpp + --8<-- "examples/README.cpp" + ``` + + Output: + + ```json + --8<-- "examples/README.output" + ``` + +## Version history + +Since version 1.0.0. diff --git a/api/json/index.html b/api/json/index.html index 2e711a6fb..877531815 100644 --- a/api/json/index.html +++ b/api/json/index.html @@ -65,4 +65,4 @@ "pi": 3.141, "size": 8 } -

Version history

Since version 1.0.0.

\ No newline at end of file +

Version history

Since version 1.0.0.

\ No newline at end of file diff --git a/api/json/index.md b/api/json/index.md new file mode 100644 index 000000000..604c8bda6 --- /dev/null +++ b/api/json/index.md @@ -0,0 +1,91 @@ +# nlohmann::json + +``` +using json = basic_json<>; +``` + +This type is the default specialization of the [basic_json](https://json.nlohmann.me/api/basic_json/index.md) class which uses the standard template types. + +## Examples + +Example + +The example below demonstrates how to use the type `nlohmann::json`. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON object + json j = + { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + { + "answer", { + {"everything", 42} + } + }, + {"list", {1, 0, 2}}, + { + "object", { + {"currency", "USD"}, + {"value", 42.99} + } + } + }; + + // add new values + j["new"]["key"]["value"] = {"another", "list"}; + + // count elements + auto s = j.size(); + j["size"] = s; + + // pretty print with indent of 4 spaces + std::cout << std::setw(4) << j << '\n'; +} +``` + +Output: + +``` +{ + "answer": { + "everything": 42 + }, + "happy": true, + "list": [ + 1, + 0, + 2 + ], + "name": "Niels", + "new": { + "key": { + "value": [ + "another", + "list" + ] + } + }, + "nothing": null, + "object": { + "currency": "USD", + "value": 42.99 + }, + "pi": 3.141, + "size": 8 +} +``` + +## Version history + +Since version 1.0.0. diff --git a/api/json_pointer.md b/api/json_pointer.md new file mode 100644 index 000000000..b1f895375 --- /dev/null +++ b/api/json_pointer.md @@ -0,0 +1,55 @@ +# nlohmann::json_pointer + +```cpp +template +class json_pointer; +``` + +A JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with +functions [`at`](../basic_json/at.md) and [`operator[]`](../basic_json/operator%5B%5D.md). Furthermore, JSON pointers +are the base for JSON patches. + +## Template parameters + +`RefStringType` +: the string type used for the reference tokens making up the JSON pointer + +!!! warning "Deprecation" + + For backwards compatibility `RefStringType` may also be a specialization of [`basic_json`](../basic_json/index.md) + in which case `string_t` will be deduced as [`basic_json::string_t`](../basic_json/string_t.md). This feature is + deprecated and may be removed in a future major version. + +## Member types + +- [**string_t**](string_t.md) - the string type used for the reference tokens + +## Member functions + +- [(constructor)](json_pointer.md) +- [**to_string**](to_string.md) - return a string representation of the JSON pointer +- [**operator string_t**](operator_string_t.md) - return a string representation of the JSON pointer +- [**operator==**](operator_eq.md) - compare: equal +- [**operator!=**](operator_ne.md) - compare: not equal +- [**operator/=**](operator_slasheq.md) - append to the end of the JSON pointer +- [**operator/**](operator_slash.md) - create JSON Pointer by appending +- [**parent_pointer**](parent_pointer.md) - returns the parent of this JSON pointer +- [**pop_back**](pop_back.md) - remove the last reference token +- [**back**](back.md) - return last reference token +- [**push_back**](push_back.md) - append an unescaped token at the end of the pointer +- [**pop_front**](pop_front.md) - remove the first reference token +- [**front**](front.md) - return first reference token +- [**push_front**](push_front.md) - append an unescaped token at the start of the pointer +- [**empty**](empty.md) - return whether the pointer points to the root document + +## Literals + +- [**operator""_json_pointer**](../operator_literal_json_pointer.md) - user-defined string literal for JSON pointers +## See also + +- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901) + +## Version history + +- Added in version 2.0.0. +- Changed template parameter from `basic_json` to string type in version 3.11.0. diff --git a/api/json_pointer/back.md b/api/json_pointer/back.md new file mode 100644 index 000000000..7b798e368 --- /dev/null +++ b/api/json_pointer/back.md @@ -0,0 +1,40 @@ +# nlohmann::json_pointer::back + +```cpp +const string_t& back() const; +``` + +Return the last reference token. + +## Return value + +Last reference token. + +## Exceptions + +Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +??? example + + The example shows the usage of `back`. + + ```cpp + --8<-- "examples/json_pointer__back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__back.output" + ``` + +## Version history + +- Added in version 3.6.0. +- Changed return type to `string_t` in version 3.11.0. diff --git a/api/json_pointer/back/index.html b/api/json_pointer/back/index.html index 12caf78f4..b22235bd3 100644 --- a/api/json_pointer/back/index.html +++ b/api/json_pointer/back/index.html @@ -16,4 +16,4 @@ }

Output:

last reference token of "/foo" is "foo"
 last reference token of "/foo/0" is "0"
-

Version history

  • Added in version 3.6.0.
  • Changed return type to string_t in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 3.6.0.
  • Changed return type to string_t in version 3.11.0.
\ No newline at end of file diff --git a/api/json_pointer/back/index.md b/api/json_pointer/back/index.md new file mode 100644 index 000000000..4bfb22ccf --- /dev/null +++ b/api/json_pointer/back/index.md @@ -0,0 +1,55 @@ +# nlohmann::json_pointer::back + +``` +const string_t& back() const; +``` + +Return the last reference token. + +## Return value + +Last reference token. + +## Exceptions + +Throws [out_of_range.405](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +Example + +The example shows the usage of `back`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1("/foo"); + json::json_pointer ptr2("/foo/0"); + + // call empty() + std::cout << "last reference token of \"" << ptr1 << "\" is \"" << ptr1.back() << "\"\n" + << "last reference token of \"" << ptr2 << "\" is \"" << ptr2.back() << "\"" << std::endl; +} +``` + +Output: + +``` +last reference token of "/foo" is "foo" +last reference token of "/foo/0" is "0" +``` + +## Version history + +- Added in version 3.6.0. +- Changed return type to `string_t` in version 3.11.0. diff --git a/api/json_pointer/empty.md b/api/json_pointer/empty.md new file mode 100644 index 000000000..96328bd23 --- /dev/null +++ b/api/json_pointer/empty.md @@ -0,0 +1,39 @@ +# nlohmann::json_pointer::empty + +```cpp +bool empty() const noexcept; +``` + +Return whether the pointer points to the root document. + +## Return value + +`#!cpp true` iff the JSON pointer points to the root document. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +??? example + + The example shows the result of `empty` for different JSON Pointers. + + ```cpp + --8<-- "examples/json_pointer__empty.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__empty.output" + ``` + +## Version history + +Added in version 3.6.0. diff --git a/api/json_pointer/empty/index.html b/api/json_pointer/empty/index.html index 1fe53ae14..78aed9bf1 100644 --- a/api/json_pointer/empty/index.html +++ b/api/json_pointer/empty/index.html @@ -23,4 +23,4 @@ "": true "/foo": false "/foo/0": false -

Version history

Added in version 3.6.0.

\ No newline at end of file +

Version history

Added in version 3.6.0.

\ No newline at end of file diff --git a/api/json_pointer/empty/index.md b/api/json_pointer/empty/index.md new file mode 100644 index 000000000..36e11b346 --- /dev/null +++ b/api/json_pointer/empty/index.md @@ -0,0 +1,61 @@ +# nlohmann::json_pointer::empty + +``` +bool empty() const noexcept; +``` + +Return whether the pointer points to the root document. + +## Return value + +`true` iff the JSON pointer points to the root document. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Constant. + +## Examples + +Example + +The example shows the result of `empty` for different JSON Pointers. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + + // call empty() + std::cout << std::boolalpha + << "\"" << ptr0 << "\": " << ptr0.empty() << '\n' + << "\"" << ptr1 << "\": " << ptr1.empty() << '\n' + << "\"" << ptr2 << "\": " << ptr2.empty() << '\n' + << "\"" << ptr3 << "\": " << ptr3.empty() << std::endl; +} +``` + +Output: + +``` +"": true +"": true +"/foo": false +"/foo/0": false +``` + +## Version history + +Added in version 3.6.0. diff --git a/api/json_pointer/front.md b/api/json_pointer/front.md new file mode 100644 index 000000000..ae078d19c --- /dev/null +++ b/api/json_pointer/front.md @@ -0,0 +1,39 @@ +# nlohmann::json_pointer::front + +```cpp +const string_t& front() const; +``` + +Return the first reference token. + +## Return value + +First reference token. + +## Exceptions + +Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +??? example + + The example shows the usage of `front`. + + ```cpp + --8<-- "examples/json_pointer__front.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__front.output" + ``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/json_pointer/front/index.html b/api/json_pointer/front/index.html index 0c345a521..a829218b9 100644 --- a/api/json_pointer/front/index.html +++ b/api/json_pointer/front/index.html @@ -16,4 +16,4 @@ }

Output:

first reference token of "/foo" is "foo"
 first reference token of "/foo/0" is "foo"
-

Version history

  • Added in version 3.12.x.
\ No newline at end of file +

Version history

  • Added in version 3.12.x.
\ No newline at end of file diff --git a/api/json_pointer/front/index.md b/api/json_pointer/front/index.md new file mode 100644 index 000000000..dd10ddaa4 --- /dev/null +++ b/api/json_pointer/front/index.md @@ -0,0 +1,54 @@ +# nlohmann::json_pointer::front + +``` +const string_t& front() const; +``` + +Return the first reference token. + +## Return value + +First reference token. + +## Exceptions + +Throws [out_of_range.405](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +Example + +The example shows the usage of `front`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1("/foo"); + json::json_pointer ptr2("/foo/0"); + + // call empty() + std::cout << "first reference token of \"" << ptr1 << "\" is \"" << ptr1.front() << "\"\n" + << "first reference token of \"" << ptr2 << "\" is \"" << ptr2.front() << "\"" << std::endl; +} +``` + +Output: + +``` +first reference token of "/foo" is "foo" +first reference token of "/foo/0" is "foo" +``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/json_pointer/index.html b/api/json_pointer/index.html index 116deace5..49754e6e2 100644 --- a/api/json_pointer/index.html +++ b/api/json_pointer/index.html @@ -1,3 +1,3 @@ Overview - JSON for Modern C++

nlohmann::json_pointer

template<typename RefStringType>
 class json_pointer;
-

A JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with functions at and operator[]. Furthermore, JSON pointers are the base for JSON patches.

Template parameters

RefStringType
the string type used for the reference tokens making up the JSON pointer

Deprecation

For backwards compatibility RefStringType may also be a specialization of basic_json in which case string_t will be deduced as basic_json::string_t. This feature is deprecated and may be removed in a future major version.

Member types

  • string_t - the string type used for the reference tokens

Member functions

  • (constructor)
  • to_string - return a string representation of the JSON pointer
  • operator string_t - return a string representation of the JSON pointer
  • operator== - compare: equal
  • operator!= - compare: not equal
  • operator/= - append to the end of the JSON pointer
  • operator/ - create JSON Pointer by appending
  • parent_pointer - returns the parent of this JSON pointer
  • pop_back - remove the last reference token
  • back - return last reference token
  • push_back - append an unescaped token at the end of the pointer
  • pop_front - remove the first reference token
  • front - return first reference token
  • push_front - append an unescaped token at the start of the pointer
  • empty - return whether the pointer points to the root document

Literals

See also

Version history

  • Added in version 2.0.0.
  • Changed template parameter from basic_json to string type in version 3.11.0.
\ No newline at end of file +

A JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with functions at and operator[]. Furthermore, JSON pointers are the base for JSON patches.

Template parameters

RefStringType
the string type used for the reference tokens making up the JSON pointer

Deprecation

For backwards compatibility RefStringType may also be a specialization of basic_json in which case string_t will be deduced as basic_json::string_t. This feature is deprecated and may be removed in a future major version.

Member types

  • string_t - the string type used for the reference tokens

Member functions

  • (constructor)
  • to_string - return a string representation of the JSON pointer
  • operator string_t - return a string representation of the JSON pointer
  • operator== - compare: equal
  • operator!= - compare: not equal
  • operator/= - append to the end of the JSON pointer
  • operator/ - create JSON Pointer by appending
  • parent_pointer - returns the parent of this JSON pointer
  • pop_back - remove the last reference token
  • back - return last reference token
  • push_back - append an unescaped token at the end of the pointer
  • pop_front - remove the first reference token
  • front - return first reference token
  • push_front - append an unescaped token at the start of the pointer
  • empty - return whether the pointer points to the root document

Literals

See also

Version history

  • Added in version 2.0.0.
  • Changed template parameter from basic_json to string type in version 3.11.0.
\ No newline at end of file diff --git a/api/json_pointer/index.md b/api/json_pointer/index.md new file mode 100644 index 000000000..cf145c284 --- /dev/null +++ b/api/json_pointer/index.md @@ -0,0 +1,51 @@ +# nlohmann::json_pointer + +``` +template +class json_pointer; +``` + +A JSON pointer defines a string syntax for identifying a specific value within a JSON document. It can be used with functions [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) and [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md). Furthermore, JSON pointers are the base for JSON patches. + +## Template parameters + +`RefStringType` : the string type used for the reference tokens making up the JSON pointer + +Deprecation + +For backwards compatibility `RefStringType` may also be a specialization of [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) in which case `string_t` will be deduced as [`basic_json::string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md). This feature is deprecated and may be removed in a future major version. + +## Member types + +- [**string_t**](https://json.nlohmann.me/api/json_pointer/string_t/index.md) - the string type used for the reference tokens + +## Member functions + +- [(constructor)](https://json.nlohmann.me/api/json_pointer/json_pointer/index.md) +- [**to_string**](https://json.nlohmann.me/api/json_pointer/to_string/index.md) - return a string representation of the JSON pointer +- [**operator string_t**](https://json.nlohmann.me/api/json_pointer/operator_string_t/index.md) - return a string representation of the JSON pointer +- [**operator==**](https://json.nlohmann.me/api/json_pointer/operator_eq/index.md) - compare: equal +- [**operator!=**](https://json.nlohmann.me/api/json_pointer/operator_ne/index.md) - compare: not equal +- [**operator/=**](https://json.nlohmann.me/api/json_pointer/operator_slasheq/index.md) - append to the end of the JSON pointer +- [**operator/**](https://json.nlohmann.me/api/json_pointer/operator_slash/index.md) - create JSON Pointer by appending +- [**parent_pointer**](https://json.nlohmann.me/api/json_pointer/parent_pointer/index.md) - returns the parent of this JSON pointer +- [**pop_back**](https://json.nlohmann.me/api/json_pointer/pop_back/index.md) - remove the last reference token +- [**back**](https://json.nlohmann.me/api/json_pointer/back/index.md) - return last reference token +- [**push_back**](https://json.nlohmann.me/api/json_pointer/push_back/index.md) - append an unescaped token at the end of the pointer +- [**pop_front**](https://json.nlohmann.me/api/json_pointer/pop_front/index.md) - remove the first reference token +- [**front**](https://json.nlohmann.me/api/json_pointer/front/index.md) - return first reference token +- [**push_front**](https://json.nlohmann.me/api/json_pointer/push_front/index.md) - append an unescaped token at the start of the pointer +- [**empty**](https://json.nlohmann.me/api/json_pointer/empty/index.md) - return whether the pointer points to the root document + +## Literals + +- [**operator""\_json_pointer**](https://json.nlohmann.me/api/operator_literal_json_pointer/index.md) - user-defined string literal for JSON pointers + +## See also + +- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901) + +## Version history + +- Added in version 2.0.0. +- Changed template parameter from `basic_json` to string type in version 3.11.0. diff --git a/api/json_pointer/json_pointer.md b/api/json_pointer/json_pointer.md new file mode 100644 index 000000000..5e7057fc9 --- /dev/null +++ b/api/json_pointer/json_pointer.md @@ -0,0 +1,41 @@ +# nlohmann::json_pointer::json_pointer + +```cpp +explicit json_pointer(const string_t& s = ""); +``` + +Create a JSON pointer according to the syntax described in +[Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). + +## Parameters + +`s` (in) +: string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value + +## Exceptions + +- Throws [parse_error.107](../../home/exceptions.md#jsonexceptionparse_error107) if the given JSON pointer `s` is + nonempty and does not begin with a slash (`/`); see example below. +- Throws [parse_error.108](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON + pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Examples + +??? example + + The example shows the construction several valid JSON pointers as well as the exceptional behavior. + + ```cpp + --8<-- "examples/json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer.output" + ``` + +## Version history + +- Added in version 2.0.0. +- Changed type of `s` to `string_t` in version 3.11.0. diff --git a/api/json_pointer/json_pointer/index.html b/api/json_pointer/json_pointer/index.html index 36fad1c82..36e1033fc 100644 --- a/api/json_pointer/json_pointer/index.html +++ b/api/json_pointer/json_pointer/index.html @@ -49,4 +49,4 @@

Output:

[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'
 [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
 [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
-

Version history

  • Added in version 2.0.0.
  • Changed type of s to string_t in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 2.0.0.
  • Changed type of s to string_t in version 3.11.0.
\ No newline at end of file diff --git a/api/json_pointer/json_pointer/index.md b/api/json_pointer/json_pointer/index.md new file mode 100644 index 000000000..e399e9ece --- /dev/null +++ b/api/json_pointer/json_pointer/index.md @@ -0,0 +1,85 @@ +# nlohmann::json_pointer::json_pointer + +``` +explicit json_pointer(const string_t& s = ""); +``` + +Create a JSON pointer according to the syntax described in [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). + +## Parameters + +`s` (in) : string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value + +## Exceptions + +- Throws [parse_error.107](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error107) if the given JSON pointer `s` is nonempty and does not begin with a slash (`/`); see example below. +- Throws [parse_error.108](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Examples + +Example + +The example shows the construction several valid JSON pointers as well as the exceptional behavior. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // correct JSON pointers + json::json_pointer p1; + json::json_pointer p2(""); + json::json_pointer p3("/"); + json::json_pointer p4("//"); + json::json_pointer p5("/foo/bar"); + json::json_pointer p6("/foo/bar/-"); + json::json_pointer p7("/foo/~0"); + json::json_pointer p8("/foo/~1"); + + // error: JSON pointer does not begin with a slash + try + { + json::json_pointer p9("foo"); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // error: JSON pointer uses escape symbol ~ not followed by 0 or 1 + try + { + json::json_pointer p10("/foo/~"); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } + + // error: JSON pointer uses escape symbol ~ not followed by 0 or 1 + try + { + json::json_pointer p11("/foo/~3"); + } + catch (const json::parse_error& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo' +[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' +[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' +``` + +## Version history + +- Added in version 2.0.0. +- Changed type of `s` to `string_t` in version 3.11.0. diff --git a/api/json_pointer/operator_eq.md b/api/json_pointer/operator_eq.md new file mode 100644 index 000000000..807ae1d0c --- /dev/null +++ b/api/json_pointer/operator_eq.md @@ -0,0 +1,113 @@ +# nlohmann::json_pointer::operator== + +```cpp +// until C++20 +template +bool operator==( + const json_pointer& lhs, + const json_pointer& rhs) noexcept; // (1) + +template +bool operator==( + const json_pointer& lhs, + const StringType& rhs); // (2) + +template +bool operator==( + const StringType& lhs, + const json_pointer& rhs); // (2) + +// since C++20 +class json_pointer { + template + bool operator==( + const json_pointer& rhs) const noexcept; // (1) + + bool operator==(const string_t& rhs) const; // (2) +}; +``` + +1. Compares two JSON pointers for equality by comparing their reference tokens. + +2. Compares a JSON pointer and a string or a string and a JSON pointer for equality by converting the string to a JSON + pointer and comparing the JSON pointers according to 1. + +## Template parameters + +`RefStringTypeLhs`, `RefStringTypeRhs` +: the string type of the left-hand side or right-hand side JSON pointer, respectively + +`StringType` +: the string type derived from the `json_pointer` operand ([`json_pointer::string_t`](string_t.md)) + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are equal + +## Exception safety + +1. No-throw guarantee: this function never throws exceptions. +2. Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. (none) +2. The function can throw the following exceptions: + - Throws [parse_error.107](../../home/exceptions.md#jsonexceptionparse_error107) if the given JSON pointer `s` is + nonempty and does not begin with a slash (`/`); see example below. + - Throws [parse_error.108](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON + pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Complexity + +Constant if `lhs` and `rhs` differ in the number of reference tokens, otherwise linear in the number of reference +tokens. + +## Notes + +!!! warning "Deprecation" + + Overload 2 is deprecated and will be removed in a future major version release. + +## Examples + +??? example "Example: (1) Comparing JSON pointers" + + The example demonstrates comparing JSON pointers. + + ```cpp + --8<-- "examples/json_pointer__operator__equal.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__equal.output" + ``` + +??? example "Example: (2) Comparing JSON pointers and strings" + + The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception. + + ```cpp + --8<-- "examples/json_pointer__operator__equal_stringtype.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__equal_stringtype.output" + ``` + +## Version history + +1. Added in version 2.1.0. Added C++20 member functions in version 3.11.2. +2. Added for backward compatibility and deprecated in version 3.11.2. diff --git a/api/json_pointer/operator_eq/index.html b/api/json_pointer/operator_eq/index.html index 182c93154..431fa2175 100644 --- a/api/json_pointer/operator_eq/index.html +++ b/api/json_pointer/operator_eq/index.html @@ -82,4 +82,4 @@ "" == "": true "/foo" == "/foo": true "bar" == "/foo": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar' -

Version history

  1. Added in version 2.1.0. Added C++20 member functions in version 3.11.2.
  2. Added for backward compatibility and deprecated in version 3.11.2.
\ No newline at end of file +

Version history

  1. Added in version 2.1.0. Added C++20 member functions in version 3.11.2.
  2. Added for backward compatibility and deprecated in version 3.11.2.
\ No newline at end of file diff --git a/api/json_pointer/operator_eq/index.md b/api/json_pointer/operator_eq/index.md new file mode 100644 index 000000000..e217c2005 --- /dev/null +++ b/api/json_pointer/operator_eq/index.md @@ -0,0 +1,160 @@ +# nlohmann::json_pointer::operator== + +``` +// until C++20 +template +bool operator==( + const json_pointer& lhs, + const json_pointer& rhs) noexcept; // (1) + +template +bool operator==( + const json_pointer& lhs, + const StringType& rhs); // (2) + +template +bool operator==( + const StringType& lhs, + const json_pointer& rhs); // (2) + +// since C++20 +class json_pointer { + template + bool operator==( + const json_pointer& rhs) const noexcept; // (1) + + bool operator==(const string_t& rhs) const; // (2) +}; +``` + +1. Compares two JSON pointers for equality by comparing their reference tokens. +1. Compares a JSON pointer and a string or a string and a JSON pointer for equality by converting the string to a JSON pointer and comparing the JSON pointers according to 1. + +## Template parameters + +`RefStringTypeLhs`, `RefStringTypeRhs` : the string type of the left-hand side or right-hand side JSON pointer, respectively + +`StringType` : the string type derived from the `json_pointer` operand ([`json_pointer::string_t`](https://json.nlohmann.me/api/json_pointer/string_t/index.md)) + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are equal + +## Exception safety + +1. No-throw guarantee: this function never throws exceptions. +1. Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. (none) +1. The function can throw the following exceptions: +1. Throws [parse_error.107](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error107) if the given JSON pointer `s` is nonempty and does not begin with a slash (`/`); see example below. +1. Throws [parse_error.108](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Complexity + +Constant if `lhs` and `rhs` differ in the number of reference tokens, otherwise linear in the number of reference tokens. + +## Notes + +Deprecation + +Overload 2 is deprecated and will be removed in a future major version release. + +## Examples + +Example: (1) Comparing JSON pointers + +The example demonstrates comparing JSON pointers. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // compare JSON pointers + std::cout << std::boolalpha + << "\"" << ptr0 << "\" == \"" << ptr0 << "\": " << (ptr0 == ptr0) << '\n' + << "\"" << ptr0 << "\" == \"" << ptr1 << "\": " << (ptr0 == ptr1) << '\n' + << "\"" << ptr1 << "\" == \"" << ptr2 << "\": " << (ptr1 == ptr2) << '\n' + << "\"" << ptr2 << "\" == \"" << ptr2 << "\": " << (ptr2 == ptr2) << std::endl; +} +``` + +Output: + +``` +"" == "": true +"" == "": true +"" == "/foo": false +"/foo" == "/foo": true +``` + +Example: (2) Comparing JSON pointers and strings + +The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // different strings + std::string str0(""); + std::string str1("/foo"); + std::string str2("bar"); + + // compare JSON pointers and strings + std::cout << std::boolalpha + << "\"" << ptr0 << "\" == \"" << str0 << "\": " << (ptr0 == str0) << '\n' + << "\"" << str0 << "\" == \"" << ptr1 << "\": " << (str0 == ptr1) << '\n' + << "\"" << ptr2 << "\" == \"" << str1 << "\": " << (ptr2 == str1) << std::endl; + + try + { + std::cout << "\"" << str2 << "\" == \"" << ptr2 << "\": " << (str2 == ptr2) << std::endl; + } + catch (const json::parse_error& ex) + { + std::cout << ex.what() << std::endl; + } +} +``` + +Output: + +``` +"" == "": true +"" == "": true +"/foo" == "/foo": true +"bar" == "/foo": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar' +``` + +## Version history + +1. Added in version 2.1.0. Added C++20 member functions in version 3.11.2. +1. Added for backward compatibility and deprecated in version 3.11.2. diff --git a/api/json_pointer/operator_ne.md b/api/json_pointer/operator_ne.md new file mode 100644 index 000000000..1f3e3247e --- /dev/null +++ b/api/json_pointer/operator_ne.md @@ -0,0 +1,109 @@ +# nlohmann::json_pointer::operator!= + +```cpp +// until C++20 +template +bool operator!=( + const json_pointer& lhs, + const json_pointer& rhs) noexcept; // (1) + +template +bool operator!=( + const json_pointer& lhs, + const StringType& rhs); // (2) + +template +bool operator!=( + const StringType& lhs, + const json_pointer& rhs); // (2) +``` + +1. Compares two JSON pointers for inequality by comparing their reference tokens. + +2. Compares a JSON pointer and a string or a string and a JSON pointer for inequality by converting the string to a + JSON pointer and comparing the JSON pointers according to 1. + +## Template parameters + +`RefStringTypeLhs`, `RefStringTypeRhs` +: the string type of the left-hand side or right-hand side JSON pointer, respectively + +`StringType` +: the string type derived from the `json_pointer` operand ([`json_pointer::string_t`](string_t.md)) + +## Parameters + +`lhs` (in) +: first value to consider + +`rhs` (in) +: second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are not equal + +## Exception safety + +1. No-throw guarantee: this function never throws exceptions. +2. Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. (none) +2. The function can throw the following exceptions: + - Throws [parse_error.107](../../home/exceptions.md#jsonexceptionparse_error107) if the given JSON pointer `s` is + nonempty and does not begin with a slash (`/`); see example below. + - Throws [parse_error.108](../../home/exceptions.md#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON + pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Complexity + +Constant if `lhs` and `rhs` differ in the number of reference tokens, otherwise linear in the number of reference +tokens. + +## Notes + +!!! note "Operator overload resolution" + + Since C++20 overload resolution will consider the _rewritten candidate_ generated from + [`operator==`](operator_eq.md). + +!!! warning "Deprecation" + + Overload 2 is deprecated and will be removed in a future major version release. + +## Examples + +??? example "Example: (1) Comparing JSON pointers" + + The example demonstrates comparing JSON pointers. + + ```cpp + --8<-- "examples/json_pointer__operator__notequal.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__notequal.output" + ``` + +??? example "Example: (2) Comparing JSON pointers and strings" + + The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception. + + ```cpp + --8<-- "examples/json_pointer__operator__notequal_stringtype.cpp" + ``` + + Output: + + ``` + --8<-- "examples/json_pointer__operator__notequal_stringtype.output" + ``` + +## Version history + +1. Added in version 2.1.0. +2. Added for backward compatibility and deprecated in version 3.11.2. diff --git a/api/json_pointer/operator_ne/index.html b/api/json_pointer/operator_ne/index.html index 9790134fb..417de72be 100644 --- a/api/json_pointer/operator_ne/index.html +++ b/api/json_pointer/operator_ne/index.html @@ -72,4 +72,4 @@ "" != "": false "/foo" != "/foo": false "bar" != "/foo": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar' -

Version history

  1. Added in version 2.1.0.
  2. Added for backward compatibility and deprecated in version 3.11.2.
\ No newline at end of file +

Version history

  1. Added in version 2.1.0.
  2. Added for backward compatibility and deprecated in version 3.11.2.
\ No newline at end of file diff --git a/api/json_pointer/operator_ne/index.md b/api/json_pointer/operator_ne/index.md new file mode 100644 index 000000000..2eec74ef5 --- /dev/null +++ b/api/json_pointer/operator_ne/index.md @@ -0,0 +1,154 @@ +# nlohmann::json_pointer::operator!= + +``` +// until C++20 +template +bool operator!=( + const json_pointer& lhs, + const json_pointer& rhs) noexcept; // (1) + +template +bool operator!=( + const json_pointer& lhs, + const StringType& rhs); // (2) + +template +bool operator!=( + const StringType& lhs, + const json_pointer& rhs); // (2) +``` + +1. Compares two JSON pointers for inequality by comparing their reference tokens. +1. Compares a JSON pointer and a string or a string and a JSON pointer for inequality by converting the string to a JSON pointer and comparing the JSON pointers according to 1. + +## Template parameters + +`RefStringTypeLhs`, `RefStringTypeRhs` : the string type of the left-hand side or right-hand side JSON pointer, respectively + +`StringType` : the string type derived from the `json_pointer` operand ([`json_pointer::string_t`](https://json.nlohmann.me/api/json_pointer/string_t/index.md)) + +## Parameters + +`lhs` (in) : first value to consider + +`rhs` (in) : second value to consider + +## Return value + +whether the values `lhs`/`*this` and `rhs` are not equal + +## Exception safety + +1. No-throw guarantee: this function never throws exceptions. +1. Strong exception safety: if an exception occurs, the original value stays intact. + +## Exceptions + +1. (none) +1. The function can throw the following exceptions: +1. Throws [parse_error.107](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error107) if the given JSON pointer `s` is nonempty and does not begin with a slash (`/`); see example below. +1. Throws [parse_error.108](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error108) if a tilde (`~`) in the given JSON pointer `s` is not followed by `0` (representing `~`) or `1` (representing `/`); see example below. + +## Complexity + +Constant if `lhs` and `rhs` differ in the number of reference tokens, otherwise linear in the number of reference tokens. + +## Notes + +Operator overload resolution + +Since C++20 overload resolution will consider the *rewritten candidate* generated from [`operator==`](https://json.nlohmann.me/api/json_pointer/operator_eq/index.md). + +Deprecation + +Overload 2 is deprecated and will be removed in a future major version release. + +## Examples + +Example: (1) Comparing JSON pointers + +The example demonstrates comparing JSON pointers. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // compare JSON pointers + std::cout << std::boolalpha + << "\"" << ptr0 << "\" != \"" << ptr0 << "\": " << (ptr0 != ptr0) << '\n' + << "\"" << ptr0 << "\" != \"" << ptr1 << "\": " << (ptr0 != ptr1) << '\n' + << "\"" << ptr1 << "\" != \"" << ptr2 << "\": " << (ptr1 != ptr2) << '\n' + << "\"" << ptr2 << "\" != \"" << ptr2 << "\": " << (ptr2 != ptr2) << std::endl; +} +``` + +Output: + +``` +"" != "": false +"" != "": false +"" != "/foo": true +"/foo" != "/foo": false +``` + +Example: (2) Comparing JSON pointers and strings + +The example demonstrates comparing JSON pointers and strings, and when doing so may raise an exception. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + + // different strings + std::string str0(""); + std::string str1("/foo"); + std::string str2("bar"); + + // compare JSON pointers and strings + std::cout << std::boolalpha + << "\"" << ptr0 << "\" != \"" << str0 << "\": " << (ptr0 != str0) << '\n' + << "\"" << str0 << "\" != \"" << ptr1 << "\": " << (str0 != ptr1) << '\n' + << "\"" << ptr2 << "\" != \"" << str1 << "\": " << (ptr2 != str1) << std::endl; + + try + { + std::cout << "\"" << str2 << "\" != \"" << ptr2 << "\": " << (str2 != ptr2) << std::endl; + } + catch (const json::parse_error& ex) + { + std::cout << ex.what() << std::endl; + } +} +``` + +Output: + +``` +"" != "": false +"" != "": false +"/foo" != "/foo": false +"bar" != "/foo": [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'bar' +``` + +## Version history + +1. Added in version 2.1.0. +1. Added for backward compatibility and deprecated in version 3.11.2. diff --git a/api/json_pointer/operator_slash.md b/api/json_pointer/operator_slash.md new file mode 100644 index 000000000..ed77b504b --- /dev/null +++ b/api/json_pointer/operator_slash.md @@ -0,0 +1,64 @@ +# nlohmann::json_pointer::operator/ + +```cpp +// (1) +json_pointer operator/(const json_pointer& lhs, const json_pointer& rhs); + +// (2) +json_pointer operator/(const json_pointer& lhs, string_t token); + +// (3) +json_pointer operator/(const json_pointer& lhs, std::size_t array_idx); +``` + +1. create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer +2. create a new JSON pointer by appending the unescaped token at the end of the JSON pointer +3. create a new JSON pointer by appending the array-index-token at the end of the JSON pointer + +## Parameters + +`lhs` (in) +: JSON pointer + +`rhs` (in) +: JSON pointer to append + +`token` (in) +: reference token to append + +`array_idx` (in) +: array index to append + +## Return value + +1. a new JSON pointer with `rhs` appended to `lhs` +2. a new JSON pointer with unescaped `token` appended to `lhs` +3. a new JSON pointer with `array_idx` appended to `lhs` + +## Complexity + +1. Linear in the length of `lhs` and `rhs`. +2. Linear in the length of `lhs`. +3. Linear in the length of `lhs`. + +## Examples + +??? example + + The example shows the usage of `operator/`. + + ```cpp + --8<-- "examples/json_pointer__operator_add_binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__operator_add_binary.output" + ``` + +## Version history + +1. Added in version 3.6.0. +2. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. +3. Added in version 3.6.0. diff --git a/api/json_pointer/operator_slash/index.html b/api/json_pointer/operator_slash/index.html index 40597c29b..823c85468 100644 --- a/api/json_pointer/operator_slash/index.html +++ b/api/json_pointer/operator_slash/index.html @@ -28,4 +28,4 @@

Output:

"/foo/bar/baz"
 "/foo/fob"
 "/foo/42"
-

Version history

  1. Added in version 3.6.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
\ No newline at end of file +

Version history

  1. Added in version 3.6.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
\ No newline at end of file diff --git a/api/json_pointer/operator_slash/index.md b/api/json_pointer/operator_slash/index.md new file mode 100644 index 000000000..db53a85bd --- /dev/null +++ b/api/json_pointer/operator_slash/index.md @@ -0,0 +1,80 @@ +# nlohmann::json_pointer::operator/ + +``` +// (1) +json_pointer operator/(const json_pointer& lhs, const json_pointer& rhs); + +// (2) +json_pointer operator/(const json_pointer& lhs, string_t token); + +// (3) +json_pointer operator/(const json_pointer& lhs, std::size_t array_idx); +``` + +1. create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer +1. create a new JSON pointer by appending the unescaped token at the end of the JSON pointer +1. create a new JSON pointer by appending the array-index-token at the end of the JSON pointer + +## Parameters + +`lhs` (in) : JSON pointer + +`rhs` (in) : JSON pointer to append + +`token` (in) : reference token to append + +`array_idx` (in) : array index to append + +## Return value + +1. a new JSON pointer with `rhs` appended to `lhs` +1. a new JSON pointer with unescaped `token` appended to `lhs` +1. a new JSON pointer with `array_idx` appended to `lhs` + +## Complexity + +1. Linear in the length of `lhs` and `rhs`. +1. Linear in the length of `lhs`. +1. Linear in the length of `lhs`. + +## Examples + +Example + +The example shows the usage of `operator/`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON pointer + json::json_pointer ptr("/foo"); + + // append a JSON Pointer + std::cout << "\"" << ptr / json::json_pointer("/bar/baz") << "\"\n"; + + // append a string + std::cout << "\"" << ptr / "fob" << "\"\n"; + + // append an array index + std::cout << "\"" << ptr / 42 << "\"" << std::endl; +} +``` + +Output: + +``` +"/foo/bar/baz" +"/foo/fob" +"/foo/42" +``` + +## Version history + +1. Added in version 3.6.0. +1. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. +1. Added in version 3.6.0. diff --git a/api/json_pointer/operator_slasheq.md b/api/json_pointer/operator_slasheq.md new file mode 100644 index 000000000..3518557d5 --- /dev/null +++ b/api/json_pointer/operator_slasheq.md @@ -0,0 +1,61 @@ +# nlohmann::json_pointer::operator/= + +```cpp +// (1) +json_pointer& operator/=(const json_pointer& ptr); + +// (2) +json_pointer& operator/=(string_t token); + +// (3) +json_pointer& operator/=(std::size_t array_idx) +``` + +1. append another JSON pointer at the end of this JSON pointer +2. append an unescaped reference token at the end of this JSON pointer +3. append an array index at the end of this JSON pointer + +## Parameters + +`ptr` (in) +: JSON pointer to append + +`token` (in) +: reference token to append + +`array_idx` (in) +: array index to append + +## Return value + +1. JSON pointer with `ptr` appended +2. JSON pointer with `token` appended without escaping `token` +3. JSON pointer with `array_idx` appended + +## Complexity + +1. Linear in the length of `ptr`. +2. Amortized constant. +3. Amortized constant. + +## Examples + +??? example + + The example shows the usage of `operator/=`. + + ```cpp + --8<-- "examples/json_pointer__operator_add.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__operator_add.output" + ``` + +## Version history + +1. Added in version 3.6.0. +2. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. +3. Added in version 3.6.0. diff --git a/api/json_pointer/operator_slasheq/index.html b/api/json_pointer/operator_slasheq/index.html index 7b0a37e2e..42d22da16 100644 --- a/api/json_pointer/operator_slasheq/index.html +++ b/api/json_pointer/operator_slasheq/index.html @@ -33,4 +33,4 @@ "/foo/bar/baz" "/foo/bar/baz/fob" "/foo/bar/baz/fob/42" -

Version history

  1. Added in version 3.6.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
\ No newline at end of file +

Version history

  1. Added in version 3.6.0.
  2. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.
  3. Added in version 3.6.0.
\ No newline at end of file diff --git a/api/json_pointer/operator_slasheq/index.md b/api/json_pointer/operator_slasheq/index.md new file mode 100644 index 000000000..33f6c19c2 --- /dev/null +++ b/api/json_pointer/operator_slasheq/index.md @@ -0,0 +1,83 @@ +# nlohmann::json_pointer::operator/= + +``` +// (1) +json_pointer& operator/=(const json_pointer& ptr); + +// (2) +json_pointer& operator/=(string_t token); + +// (3) +json_pointer& operator/=(std::size_t array_idx) +``` + +1. append another JSON pointer at the end of this JSON pointer +1. append an unescaped reference token at the end of this JSON pointer +1. append an array index at the end of this JSON pointer + +## Parameters + +`ptr` (in) : JSON pointer to append + +`token` (in) : reference token to append + +`array_idx` (in) : array index to append + +## Return value + +1. JSON pointer with `ptr` appended +1. JSON pointer with `token` appended without escaping `token` +1. JSON pointer with `array_idx` appended + +## Complexity + +1. Linear in the length of `ptr`. +1. Amortized constant. +1. Amortized constant. + +## Examples + +Example + +The example shows the usage of `operator/=`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON pointer + json::json_pointer ptr("/foo"); + std::cout << "\"" << ptr << "\"\n"; + + // append a JSON Pointer + ptr /= json::json_pointer("/bar/baz"); + std::cout << "\"" << ptr << "\"\n"; + + // append a string + ptr /= "fob"; + std::cout << "\"" << ptr << "\"\n"; + + // append an array index + ptr /= 42; + std::cout << "\"" << ptr << "\"" << std::endl; +} +``` + +Output: + +``` +"/foo" +"/foo/bar/baz" +"/foo/bar/baz/fob" +"/foo/bar/baz/fob/42" +``` + +## Version history + +1. Added in version 3.6.0. +1. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. +1. Added in version 3.6.0. diff --git a/api/json_pointer/operator_string_t.md b/api/json_pointer/operator_string_t.md new file mode 100644 index 000000000..89898fa4f --- /dev/null +++ b/api/json_pointer/operator_string_t.md @@ -0,0 +1,52 @@ +# nlohmann::json_pointer::operator string_t + +```cpp +operator string_t() const +``` + +Return a string representation of the JSON pointer. + +## Return value + +A string representation of the JSON pointer + +## Possible implementation + +```cpp +operator string_t() const +{ + return to_string(); +} +``` + +## Notes + +!!! warning "Deprecation" + + This function is deprecated in favor of [`to_string`](to_string.md) and will be removed in a future major version + release. + +## Examples + +??? example + + The example shows how JSON Pointers can be implicitly converted to strings. + + ```cpp + --8<-- "examples/json_pointer__operator_string_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__operator_string_t.output" + ``` + +## See also + +- [string_t](../basic_json/string_t.md)- type for strings + +## Version history + +- Since version 2.0.0. +- Changed type to `string_t` and deprecated in version 3.11.0. diff --git a/api/json_pointer/operator_string_t/index.html b/api/json_pointer/operator_string_t/index.html index fe33148f7..d4568b56f 100644 --- a/api/json_pointer/operator_string_t/index.html +++ b/api/json_pointer/operator_string_t/index.html @@ -24,4 +24,4 @@ }

Output:

/foo/0
 /a~1b
-

See also

Version history

  • Since version 2.0.0.
  • Changed type to string_t and deprecated in version 3.11.0.
\ No newline at end of file +

See also

Version history

  • Since version 2.0.0.
  • Changed type to string_t and deprecated in version 3.11.0.
\ No newline at end of file diff --git a/api/json_pointer/operator_string_t/index.md b/api/json_pointer/operator_string_t/index.md new file mode 100644 index 000000000..48b3c96e9 --- /dev/null +++ b/api/json_pointer/operator_string_t/index.md @@ -0,0 +1,70 @@ +# nlohmann::json_pointer::operator string_t + +``` +operator string_t() const +``` + +Return a string representation of the JSON pointer. + +## Return value + +A string representation of the JSON pointer + +## Possible implementation + +``` +operator string_t() const +{ + return to_string(); +} +``` + +## Notes + +Deprecation + +This function is deprecated in favor of [`to_string`](https://json.nlohmann.me/api/json_pointer/to_string/index.md) and will be removed in a future major version release. + +## Examples + +Example + +The example shows how JSON Pointers can be implicitly converted to strings. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1("/foo/0"); + json::json_pointer ptr2("/a~1b"); + + // implicit conversion to string + std::string s; + s += ptr1; + s += "\n"; + s += ptr2; + + std::cout << s << std::endl; +} +``` + +Output: + +``` +/foo/0 +/a~1b +``` + +## See also + +- [string_t](https://json.nlohmann.me/api/basic_json/string_t/index.md)- type for strings + +## Version history + +- Since version 2.0.0. +- Changed type to `string_t` and deprecated in version 3.11.0. diff --git a/api/json_pointer/parent_pointer.md b/api/json_pointer/parent_pointer.md new file mode 100644 index 000000000..d37889e7e --- /dev/null +++ b/api/json_pointer/parent_pointer.md @@ -0,0 +1,44 @@ +# nlohmann::json_pointer::parent_pointer + +```cpp +json_pointer parent_pointer() const; +``` + +Returns the parent of this JSON pointer. + +## Return value + +Parent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear in the length of the JSON pointer. + +## Examples + +??? example + + The example shows the result of `parent_pointer` for different JSON Pointers. + + ```cpp + --8<-- "examples/json_pointer__parent_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__parent_pointer.output" + ``` + +## See also + +- [pop_back](pop_back.md) remove the last reference token +- [back](back.md) return the last reference token + +## Version history + +Added in version 3.6.0. diff --git a/api/json_pointer/parent_pointer/index.html b/api/json_pointer/parent_pointer/index.html index 1321fb789..d31b93064 100644 --- a/api/json_pointer/parent_pointer/index.html +++ b/api/json_pointer/parent_pointer/index.html @@ -20,4 +20,4 @@

Output:

parent of "" is ""
 parent of "/foo" is ""
 parent of "/foo/0" is "/foo"
-

See also

  • pop_back remove the last reference token
  • back return the last reference token

Version history

Added in version 3.6.0.

\ No newline at end of file +

See also

  • pop_back remove the last reference token
  • back return the last reference token

Version history

Added in version 3.6.0.

\ No newline at end of file diff --git a/api/json_pointer/parent_pointer/index.md b/api/json_pointer/parent_pointer/index.md new file mode 100644 index 000000000..4d11ce6cf --- /dev/null +++ b/api/json_pointer/parent_pointer/index.md @@ -0,0 +1,63 @@ +# nlohmann::json_pointer::parent_pointer + +``` +json_pointer parent_pointer() const; +``` + +Returns the parent of this JSON pointer. + +## Return value + +Parent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned. + +## Exception safety + +No-throw guarantee: this function never throws exceptions. + +## Complexity + +Linear in the length of the JSON pointer. + +## Examples + +Example + +The example shows the result of `parent_pointer` for different JSON Pointers. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + + // call parent_pointer() + std::cout << std::boolalpha + << "parent of \"" << ptr1 << "\" is \"" << ptr1.parent_pointer() << "\"\n" + << "parent of \"" << ptr2 << "\" is \"" << ptr2.parent_pointer() << "\"\n" + << "parent of \"" << ptr3 << "\" is \"" << ptr3.parent_pointer() << "\"" << std::endl; +} +``` + +Output: + +``` +parent of "" is "" +parent of "/foo" is "" +parent of "/foo/0" is "/foo" +``` + +## See also + +- [pop_back](https://json.nlohmann.me/api/json_pointer/pop_back/index.md) remove the last reference token +- [back](https://json.nlohmann.me/api/json_pointer/back/index.md) return the last reference token + +## Version history + +Added in version 3.6.0. diff --git a/api/json_pointer/pop_back.md b/api/json_pointer/pop_back.md new file mode 100644 index 000000000..16b1cd4da --- /dev/null +++ b/api/json_pointer/pop_back.md @@ -0,0 +1,35 @@ +# nlohmann::json_pointer::pop_back + +```cpp +void pop_back(); +``` + +Remove the last reference token. + +## Exceptions + +Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +??? example + + The example shows the usage of `pop_back`. + + ```cpp + --8<-- "examples/json_pointer__pop_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__pop_back.output" + ``` + +## Version history + +Added in version 3.6.0. diff --git a/api/json_pointer/pop_back/index.html b/api/json_pointer/pop_back/index.html index 52a92bc2b..f16dac06f 100644 --- a/api/json_pointer/pop_back/index.html +++ b/api/json_pointer/pop_back/index.html @@ -24,4 +24,4 @@ "/foo/bar" "/foo" "" -

Version history

Added in version 3.6.0.

\ No newline at end of file +

Version history

Added in version 3.6.0.

\ No newline at end of file diff --git a/api/json_pointer/pop_back/index.md b/api/json_pointer/pop_back/index.md new file mode 100644 index 000000000..9a1e3facc --- /dev/null +++ b/api/json_pointer/pop_back/index.md @@ -0,0 +1,58 @@ +# nlohmann::json_pointer::pop_back + +``` +void pop_back(); +``` + +Remove the last reference token. + +## Exceptions + +Throws [out_of_range.405](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Constant. + +## Examples + +Example + +The example shows the usage of `pop_back`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create empty JSON Pointer + json::json_pointer ptr("/foo/bar/baz"); + std::cout << "\"" << ptr << "\"\n"; + + // call pop_back() + ptr.pop_back(); + std::cout << "\"" << ptr << "\"\n"; + + ptr.pop_back(); + std::cout << "\"" << ptr << "\"\n"; + + ptr.pop_back(); + std::cout << "\"" << ptr << "\"\n"; +} +``` + +Output: + +``` +"/foo/bar/baz" +"/foo/bar" +"/foo" +"" +``` + +## Version history + +Added in version 3.6.0. diff --git a/api/json_pointer/pop_front.md b/api/json_pointer/pop_front.md new file mode 100644 index 000000000..ecd13ad28 --- /dev/null +++ b/api/json_pointer/pop_front.md @@ -0,0 +1,35 @@ +# nlohmann::json_pointer::pop_front + +```cpp +void pop_front(); +``` + +Remove the first reference token. + +## Exceptions + +Throws [out_of_range.405](../../home/exceptions.md#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Linear in the number of reference tokens in the `json_pointer`. + +## Examples + +??? example + + The example shows the usage of `pop_front`. + + ```cpp + --8<-- "examples/json_pointer__pop_front.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__pop_front.output" + ``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/json_pointer/pop_front/index.html b/api/json_pointer/pop_front/index.html index 3e4d66357..41dae584a 100644 --- a/api/json_pointer/pop_front/index.html +++ b/api/json_pointer/pop_front/index.html @@ -24,4 +24,4 @@ "/bar/baz" "/baz" "" -

Version history

  • Added in version 3.12.x.
\ No newline at end of file +

Version history

  • Added in version 3.12.x.
\ No newline at end of file diff --git a/api/json_pointer/pop_front/index.md b/api/json_pointer/pop_front/index.md new file mode 100644 index 000000000..b5c7a1105 --- /dev/null +++ b/api/json_pointer/pop_front/index.md @@ -0,0 +1,58 @@ +# nlohmann::json_pointer::pop_front + +``` +void pop_front(); +``` + +Remove the first reference token. + +## Exceptions + +Throws [out_of_range.405](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range405) if the JSON pointer has no parent. + +## Complexity + +Linear in the number of reference tokens in the `json_pointer`. + +## Examples + +Example + +The example shows the usage of `pop_front`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create empty JSON Pointer + json::json_pointer ptr("/foo/bar/baz"); + std::cout << "\"" << ptr << "\"\n"; + + // call pop_front() + ptr.pop_front(); + std::cout << "\"" << ptr << "\"\n"; + + ptr.pop_front(); + std::cout << "\"" << ptr << "\"\n"; + + ptr.pop_front(); + std::cout << "\"" << ptr << "\"\n"; +} +``` + +Output: + +``` +"/foo/bar/baz" +"/bar/baz" +"/baz" +"" +``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/json_pointer/push_back.md b/api/json_pointer/push_back.md new file mode 100644 index 000000000..c1c19cb8d --- /dev/null +++ b/api/json_pointer/push_back.md @@ -0,0 +1,39 @@ +# nlohmann::json_pointer::push_back + +```cpp +void push_back(const string_t& token); + +void push_back(string_t&& token); +``` + +Append an unescaped token at the end of the reference pointer. + +## Parameters + +`token` (in) +: token to add + +## Complexity + +Amortized constant. + +## Examples + +??? example + + The example shows the result of `push_back` for different JSON Pointers. + + ```cpp + --8<-- "examples/json_pointer__push_back.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__push_back.output" + ``` + +## Version history + +- Added in version 3.6.0. +- Changed type of `token` to `string_t` in version 3.11.0. diff --git a/api/json_pointer/push_back/index.html b/api/json_pointer/push_back/index.html index a118bd537..37d6f79c2 100644 --- a/api/json_pointer/push_back/index.html +++ b/api/json_pointer/push_back/index.html @@ -26,4 +26,4 @@ "/foo" "/foo/0" "/foo/0/bar" -

Version history

  • Added in version 3.6.0.
  • Changed type of token to string_t in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 3.6.0.
  • Changed type of token to string_t in version 3.11.0.
\ No newline at end of file diff --git a/api/json_pointer/push_back/index.md b/api/json_pointer/push_back/index.md new file mode 100644 index 000000000..ecf181a56 --- /dev/null +++ b/api/json_pointer/push_back/index.md @@ -0,0 +1,61 @@ +# nlohmann::json_pointer::push_back + +``` +void push_back(const string_t& token); + +void push_back(string_t&& token); +``` + +Append an unescaped token at the end of the reference pointer. + +## Parameters + +`token` (in) : token to add + +## Complexity + +Amortized constant. + +## Examples + +Example + +The example shows the result of `push_back` for different JSON Pointers. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create empty JSON Pointer + json::json_pointer ptr; + std::cout << "\"" << ptr << "\"\n"; + + // call push_back() + ptr.push_back("foo"); + std::cout << "\"" << ptr << "\"\n"; + + ptr.push_back("0"); + std::cout << "\"" << ptr << "\"\n"; + + ptr.push_back("bar"); + std::cout << "\"" << ptr << "\"\n"; +} +``` + +Output: + +``` +"" +"/foo" +"/foo/0" +"/foo/0/bar" +``` + +## Version history + +- Added in version 3.6.0. +- Changed type of `token` to `string_t` in version 3.11.0. diff --git a/api/json_pointer/push_front.md b/api/json_pointer/push_front.md new file mode 100644 index 000000000..dd522a48d --- /dev/null +++ b/api/json_pointer/push_front.md @@ -0,0 +1,38 @@ +# nlohmann::json_pointer::push_front + +```cpp +void push_front(const string_t& token); + +void push_front(string_t&& token); +``` + +Append an unescaped token at the start of the reference pointer. + +## Parameters + +`token` (in) +: token to add + +## Complexity + +Linear in the number of reference tokens in the `json_pointer`. + +## Examples + +??? example + + The example shows the result of `push_front` for different JSON Pointers. + + ```cpp + --8<-- "examples/json_pointer__push_front.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__push_front.output" + ``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/json_pointer/push_front/index.html b/api/json_pointer/push_front/index.html index 6f9fb72bd..0930847e2 100644 --- a/api/json_pointer/push_front/index.html +++ b/api/json_pointer/push_front/index.html @@ -26,4 +26,4 @@ "/foo" "/0/foo" "/bar/0/foo" -

Version history

  • Added in version 3.12.x.
\ No newline at end of file +

Version history

  • Added in version 3.12.x.
\ No newline at end of file diff --git a/api/json_pointer/push_front/index.md b/api/json_pointer/push_front/index.md new file mode 100644 index 000000000..d17c001bb --- /dev/null +++ b/api/json_pointer/push_front/index.md @@ -0,0 +1,60 @@ +# nlohmann::json_pointer::push_front + +``` +void push_front(const string_t& token); + +void push_front(string_t&& token); +``` + +Append an unescaped token at the start of the reference pointer. + +## Parameters + +`token` (in) : token to add + +## Complexity + +Linear in the number of reference tokens in the `json_pointer`. + +## Examples + +Example + +The example shows the result of `push_front` for different JSON Pointers. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create empty JSON Pointer + json::json_pointer ptr; + std::cout << "\"" << ptr << "\"\n"; + + // call push_front() + ptr.push_front("foo"); + std::cout << "\"" << ptr << "\"\n"; + + ptr.push_front("0"); + std::cout << "\"" << ptr << "\"\n"; + + ptr.push_front("bar"); + std::cout << "\"" << ptr << "\"\n"; +} +``` + +Output: + +``` +"" +"/foo" +"/0/foo" +"/bar/0/foo" +``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/json_pointer/string_t.md b/api/json_pointer/string_t.md new file mode 100644 index 000000000..c8527bc9c --- /dev/null +++ b/api/json_pointer/string_t.md @@ -0,0 +1,28 @@ +# nlohmann::json_pointer::string_t +```cpp +using string_t = RefStringType; +``` + +The string type used for the reference tokens making up the JSON pointer. + +See [`basic_json::string_t`](../basic_json/string_t.md) for more information. + +## Examples + +??? example + + The example shows the type `string_t` and its relation to `basic_json::string_t`. + + ```cpp + --8<-- "examples/json_pointer__string_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__string_t.output" + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/json_pointer/string_t/index.html b/api/json_pointer/string_t/index.html index 556e80220..39ca19f3b 100644 --- a/api/json_pointer/string_t/index.html +++ b/api/json_pointer/string_t/index.html @@ -14,4 +14,4 @@ }

Output:

This is a string.
 true
-

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/json_pointer/string_t/index.md b/api/json_pointer/string_t/index.md new file mode 100644 index 000000000..0f1325856 --- /dev/null +++ b/api/json_pointer/string_t/index.md @@ -0,0 +1,42 @@ +# nlohmann::json_pointer::string_t + +``` +using string_t = RefStringType; +``` + +The string type used for the reference tokens making up the JSON pointer. + +See [`basic_json::string_t`](https://json.nlohmann.me/api/basic_json/string_t/index.md) for more information. + +## Examples + +Example + +The example shows the type `string_t` and its relation to `basic_json::string_t`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + json::json_pointer::string_t s = "This is a string."; + + std::cout << s << std::endl; + + std::cout << std::boolalpha << std::is_same::value << std::endl; +} +``` + +Output: + +``` +This is a string. +true +``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/json_pointer/to_string.md b/api/json_pointer/to_string.md new file mode 100644 index 000000000..fae3abe5f --- /dev/null +++ b/api/json_pointer/to_string.md @@ -0,0 +1,40 @@ +# nlohmann::json_pointer::to_string + +```cpp +string_t to_string() const; +``` + +Return a string representation of the JSON pointer. + +## Return value + +A string representation of the JSON pointer + +## Notes + +For each JSON pointer `ptr`, it holds: + +```cpp +ptr == json_pointer(ptr.to_string()); +``` + +## Examples + +??? example + + The example shows the result of `to_string`. + + ```cpp + --8<-- "examples/json_pointer__to_string.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_pointer__to_string.output" + ``` + +## Version history + +- Since version 2.0.0. +- Changed return type to `string_t` in version 3.11.0. diff --git a/api/json_pointer/to_string/index.html b/api/json_pointer/to_string/index.html index 2690f3cf5..3aded8fbc 100644 --- a/api/json_pointer/to_string/index.html +++ b/api/json_pointer/to_string/index.html @@ -46,4 +46,4 @@ "/k"l" "/ " "/m~0n" -

Version history

  • Since version 2.0.0.
  • Changed return type to string_t in version 3.11.0.
\ No newline at end of file +

Version history

  • Since version 2.0.0.
  • Changed return type to string_t in version 3.11.0.
\ No newline at end of file diff --git a/api/json_pointer/to_string/index.md b/api/json_pointer/to_string/index.md new file mode 100644 index 000000000..357aac477 --- /dev/null +++ b/api/json_pointer/to_string/index.md @@ -0,0 +1,84 @@ +# nlohmann::json_pointer::to_string + +``` +string_t to_string() const; +``` + +Return a string representation of the JSON pointer. + +## Return value + +A string representation of the JSON pointer + +## Notes + +For each JSON pointer `ptr`, it holds: + +``` +ptr == json_pointer(ptr.to_string()); +``` + +## Examples + +Example + +The example shows the result of `to_string`. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + json::json_pointer ptr4("/"); + json::json_pointer ptr5("/a~1b"); + json::json_pointer ptr6("/c%d"); + json::json_pointer ptr7("/e^f"); + json::json_pointer ptr8("/g|h"); + json::json_pointer ptr9("/i\\j"); + json::json_pointer ptr10("/k\"l"); + json::json_pointer ptr11("/ "); + json::json_pointer ptr12("/m~0n"); + + std::cout << "\"" << ptr1.to_string() << "\"\n" + << "\"" << ptr2.to_string() << "\"\n" + << "\"" << ptr3.to_string() << "\"\n" + << "\"" << ptr4.to_string() << "\"\n" + << "\"" << ptr5.to_string() << "\"\n" + << "\"" << ptr6.to_string() << "\"\n" + << "\"" << ptr7.to_string() << "\"\n" + << "\"" << ptr8.to_string() << "\"\n" + << "\"" << ptr9.to_string() << "\"\n" + << "\"" << ptr10.to_string() << "\"\n" + << "\"" << ptr11.to_string() << "\"\n" + << "\"" << ptr12.to_string() << "\"" << std::endl; +} +``` + +Output: + +``` +"" +"/foo" +"/foo/0" +"/" +"/a~1b" +"/c%d" +"/e^f" +"/g|h" +"/i\j" +"/k"l" +"/ " +"/m~0n" +``` + +## Version history + +- Since version 2.0.0. +- Changed return type to `string_t` in version 3.11.0. diff --git a/api/json_sax.md b/api/json_sax.md new file mode 100644 index 000000000..d66b7a254 --- /dev/null +++ b/api/json_sax.md @@ -0,0 +1,44 @@ +# nlohmann::json_sax + +```cpp +template +struct json_sax; +``` + +This class describes the SAX interface used by [sax_parse](../basic_json/sax_parse.md). Each function is called in +different situations while the input is parsed. The boolean return value informs the parser whether to continue +processing the input. + +## Template parameters + +`BasicJsonType` +: a specialization of [`basic_json`](../basic_json/index.md) + +## Member types + +- [**number_integer_t**](../basic_json/number_integer_t.md) - `BasicJsonType`'s type for numbers (integer) +- [**number_unsigned_t**](../basic_json/number_unsigned_t.md) - `BasicJsonType`'s type for numbers (unsigned) +- [**number_float_t**](../basic_json/number_float_t.md) - `BasicJsonType`'s type for numbers (floating-point) +- [**string_t**](../basic_json/string_t.md) - `BasicJsonType`'s type for strings +- [**binary_t**](../basic_json/binary_t.md) - `BasicJsonType`'s type for binary arrays + +## Member functions + +- [**binary**](binary.md) (_virtual_) - a binary value was read +- [**boolean**](boolean.md) (_virtual_) - a boolean value was read +- [**end_array**](end_array.md) (_virtual_) - the end of an array was read +- [**end_object**](end_object.md) (_virtual_) - the end of an object was read +- [**key**](key.md) (_virtual_) - an object key was read +- [**null**](null.md) (_virtual_) - a null value was read +- [**number_float**](number_float.md) (_virtual_) - a floating-point number was read +- [**number_integer**](number_integer.md) (_virtual_) - an integer number was read +- [**number_unsigned**](number_unsigned.md) (_virtual_) - an unsigned integer number was read +- [**parse_error**](parse_error.md) (_virtual_) - a parse error occurred +- [**start_array**](start_array.md) (_virtual_) - the beginning of an array was read +- [**start_object**](start_object.md) (_virtual_) - the beginning of an object was read +- [**string**](string.md) (_virtual_) - a string value was read + +## Version history + +- Added in version 3.2.0. +- Support for binary values (`binary_t`, `binary`) added in version 3.8.0. diff --git a/api/json_sax/binary.md b/api/json_sax/binary.md new file mode 100644 index 000000000..fc0980e20 --- /dev/null +++ b/api/json_sax/binary.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::binary + +```cpp +virtual bool binary(binary_t& val) = 0; +``` + +A binary value was read. + +## Parameters + +`val` (in) +: binary value + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed binary value. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse__binary.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse__binary.output" + ``` + +## Version history + +- Added in version 3.8.0. diff --git a/api/json_sax/binary/index.html b/api/json_sax/binary/index.html index 32c33fb61..edde25040 100644 --- a/api/json_sax/binary/index.html +++ b/api/json_sax/binary/index.html @@ -116,4 +116,4 @@

Output:

binary(val=[...])
 
 result: true
-

Version history

  • Added in version 3.8.0.
\ No newline at end of file +

Version history

  • Added in version 3.8.0.
\ No newline at end of file diff --git a/api/json_sax/binary/index.md b/api/json_sax/binary/index.md new file mode 100644 index 000000000..bd2c24473 --- /dev/null +++ b/api/json_sax/binary/index.md @@ -0,0 +1,154 @@ +# nlohmann::json_sax::binary + +``` +virtual bool binary(binary_t& val) = 0; +``` + +A binary value was read. + +## Parameters + +`val` (in) : binary value + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed binary value. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // CBOR byte string + std::vector vec = {{0x44, 0xcA, 0xfe, 0xba, 0xbe}}; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse CBOR + bool result = json::sax_parse(vec, &sec, json::input_format_t::cbor); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +binary(val=[...]) + +result: true +``` + +## Version history + +- Added in version 3.8.0. diff --git a/api/json_sax/boolean.md b/api/json_sax/boolean.md new file mode 100644 index 000000000..fdf294562 --- /dev/null +++ b/api/json_sax/boolean.md @@ -0,0 +1,36 @@ +# nlohmann::json_sax::boolean + +```cpp +virtual bool boolean(bool val) = 0; +``` + +A boolean value was read. + +## Parameters + +`val` (in) +: boolean value + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/boolean/index.html b/api/json_sax/boolean/index.html index 782fe93d4..bc17ee518 100644 --- a/api/json_sax/boolean/index.html +++ b/api/json_sax/boolean/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/boolean/index.md b/api/json_sax/boolean/index.md new file mode 100644 index 000000000..9b99e4ccc --- /dev/null +++ b/api/json_sax/boolean/index.md @@ -0,0 +1,201 @@ +# nlohmann::json_sax::boolean + +``` +virtual bool boolean(bool val) = 0; +``` + +A boolean value was read. + +## Parameters + +`val` (in) : boolean value + +## Return value + +Whether parsing should proceed. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/end_array.md b/api/json_sax/end_array.md new file mode 100644 index 000000000..9c12e40a5 --- /dev/null +++ b/api/json_sax/end_array.md @@ -0,0 +1,31 @@ +# nlohmann::json_sax::end_array + +```cpp +virtual bool end_array() = 0; +``` + +The end of an array was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/end_array/index.html b/api/json_sax/end_array/index.html index 646005708..5a1a92cc9 100644 --- a/api/json_sax/end_array/index.html +++ b/api/json_sax/end_array/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/end_array/index.md b/api/json_sax/end_array/index.md new file mode 100644 index 000000000..43c7f9080 --- /dev/null +++ b/api/json_sax/end_array/index.md @@ -0,0 +1,197 @@ +# nlohmann::json_sax::end_array + +``` +virtual bool end_array() = 0; +``` + +The end of an array was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/end_object.md b/api/json_sax/end_object.md new file mode 100644 index 000000000..601c94a4a --- /dev/null +++ b/api/json_sax/end_object.md @@ -0,0 +1,31 @@ +# nlohmann::json_sax::end_object + +```cpp +virtual bool end_object() = 0; +``` + +The end of an object was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/end_object/index.html b/api/json_sax/end_object/index.html index 35fcc3619..70b09d8c6 100644 --- a/api/json_sax/end_object/index.html +++ b/api/json_sax/end_object/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/end_object/index.md b/api/json_sax/end_object/index.md new file mode 100644 index 000000000..02d083330 --- /dev/null +++ b/api/json_sax/end_object/index.md @@ -0,0 +1,197 @@ +# nlohmann::json_sax::end_object + +``` +virtual bool end_object() = 0; +``` + +The end of an object was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/index.html b/api/json_sax/index.html index 45c93d714..24727f973 100644 --- a/api/json_sax/index.html +++ b/api/json_sax/index.html @@ -1,3 +1,3 @@ Overview - JSON for Modern C++

nlohmann::json_sax

template<typename BasicJsonType>
 struct json_sax;
-

This class describes the SAX interface used by sax_parse. Each function is called in different situations while the input is parsed. The boolean return value informs the parser whether to continue processing the input.

Template parameters

BasicJsonType
a specialization of basic_json

Member types

Member functions

  • binary (virtual) - a binary value was read
  • boolean (virtual) - a boolean value was read
  • end_array (virtual) - the end of an array was read
  • end_object (virtual) - the end of an object was read
  • key (virtual) - an object key was read
  • null (virtual) - a null value was read
  • number_float (virtual) - a floating-point number was read
  • number_integer (virtual) - an integer number was read
  • number_unsigned (virtual) - an unsigned integer number was read
  • parse_error (virtual) - a parse error occurred
  • start_array (virtual) - the beginning of an array was read
  • start_object (virtual) - the beginning of an object was read
  • string (virtual) - a string value was read

Version history

  • Added in version 3.2.0.
  • Support for binary values (binary_t, binary) added in version 3.8.0.
\ No newline at end of file +

This class describes the SAX interface used by sax_parse. Each function is called in different situations while the input is parsed. The boolean return value informs the parser whether to continue processing the input.

Template parameters

BasicJsonType
a specialization of basic_json

Member types

Member functions

  • binary (virtual) - a binary value was read
  • boolean (virtual) - a boolean value was read
  • end_array (virtual) - the end of an array was read
  • end_object (virtual) - the end of an object was read
  • key (virtual) - an object key was read
  • null (virtual) - a null value was read
  • number_float (virtual) - a floating-point number was read
  • number_integer (virtual) - an integer number was read
  • number_unsigned (virtual) - an unsigned integer number was read
  • parse_error (virtual) - a parse error occurred
  • start_array (virtual) - the beginning of an array was read
  • start_object (virtual) - the beginning of an object was read
  • string (virtual) - a string value was read

Version history

  • Added in version 3.2.0.
  • Support for binary values (binary_t, binary) added in version 3.8.0.
\ No newline at end of file diff --git a/api/json_sax/index.md b/api/json_sax/index.md new file mode 100644 index 000000000..8f40ae67b --- /dev/null +++ b/api/json_sax/index.md @@ -0,0 +1,41 @@ +# nlohmann::json_sax + +``` +template +struct json_sax; +``` + +This class describes the SAX interface used by [sax_parse](https://json.nlohmann.me/api/basic_json/sax_parse/index.md). Each function is called in different situations while the input is parsed. The boolean return value informs the parser whether to continue processing the input. + +## Template parameters + +`BasicJsonType` : a specialization of [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) + +## Member types + +- [**number_integer_t**](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) - `BasicJsonType`'s type for numbers (integer) +- [**number_unsigned_t**](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) - `BasicJsonType`'s type for numbers (unsigned) +- [**number_float_t**](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) - `BasicJsonType`'s type for numbers (floating-point) +- [**string_t**](https://json.nlohmann.me/api/basic_json/string_t/index.md) - `BasicJsonType`'s type for strings +- [**binary_t**](https://json.nlohmann.me/api/basic_json/binary_t/index.md) - `BasicJsonType`'s type for binary arrays + +## Member functions + +- [**binary**](https://json.nlohmann.me/api/json_sax/binary/index.md) (*virtual*) - a binary value was read +- [**boolean**](https://json.nlohmann.me/api/json_sax/boolean/index.md) (*virtual*) - a boolean value was read +- [**end_array**](https://json.nlohmann.me/api/json_sax/end_array/index.md) (*virtual*) - the end of an array was read +- [**end_object**](https://json.nlohmann.me/api/json_sax/end_object/index.md) (*virtual*) - the end of an object was read +- [**key**](https://json.nlohmann.me/api/json_sax/key/index.md) (*virtual*) - an object key was read +- [**null**](https://json.nlohmann.me/api/json_sax/null/index.md) (*virtual*) - a null value was read +- [**number_float**](https://json.nlohmann.me/api/json_sax/number_float/index.md) (*virtual*) - a floating-point number was read +- [**number_integer**](https://json.nlohmann.me/api/json_sax/number_integer/index.md) (*virtual*) - an integer number was read +- [**number_unsigned**](https://json.nlohmann.me/api/json_sax/number_unsigned/index.md) (*virtual*) - an unsigned integer number was read +- [**parse_error**](https://json.nlohmann.me/api/json_sax/parse_error/index.md) (*virtual*) - a parse error occurred +- [**start_array**](https://json.nlohmann.me/api/json_sax/start_array/index.md) (*virtual*) - the beginning of an array was read +- [**start_object**](https://json.nlohmann.me/api/json_sax/start_object/index.md) (*virtual*) - the beginning of an object was read +- [**string**](https://json.nlohmann.me/api/json_sax/string/index.md) (*virtual*) - a string value was read + +## Version history + +- Added in version 3.2.0. +- Support for binary values (`binary_t`, `binary`) added in version 3.8.0. diff --git a/api/json_sax/key.md b/api/json_sax/key.md new file mode 100644 index 000000000..31fd6c1d1 --- /dev/null +++ b/api/json_sax/key.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::key + +```cpp +virtual bool key(string_t& val) = 0; +``` + +An object key was read. + +## Parameters + +`val` (in) +: object key + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed object key value. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/key/index.html b/api/json_sax/key/index.html index be8127ff4..558d83fbe 100644 --- a/api/json_sax/key/index.html +++ b/api/json_sax/key/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/key/index.md b/api/json_sax/key/index.md new file mode 100644 index 000000000..99c9a8bbc --- /dev/null +++ b/api/json_sax/key/index.md @@ -0,0 +1,205 @@ +# nlohmann::json_sax::key + +``` +virtual bool key(string_t& val) = 0; +``` + +An object key was read. + +## Parameters + +`val` (in) : object key + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed object key value. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/null.md b/api/json_sax/null.md new file mode 100644 index 000000000..9354ede6c --- /dev/null +++ b/api/json_sax/null.md @@ -0,0 +1,31 @@ +# nlohmann::json_sax::null + +```cpp +virtual bool null() = 0; +``` + +A null value was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/null/index.html b/api/json_sax/null/index.html index cd2ec71ea..1b63cbe18 100644 --- a/api/json_sax/null/index.html +++ b/api/json_sax/null/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/null/index.md b/api/json_sax/null/index.md new file mode 100644 index 000000000..8f6cac729 --- /dev/null +++ b/api/json_sax/null/index.md @@ -0,0 +1,197 @@ +# nlohmann::json_sax::null + +``` +virtual bool null() = 0; +``` + +A null value was read. + +## Return value + +Whether parsing should proceed. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/number_float.md b/api/json_sax/number_float.md new file mode 100644 index 000000000..17799401e --- /dev/null +++ b/api/json_sax/number_float.md @@ -0,0 +1,39 @@ +# nlohmann::json_sax::number_float + +```cpp +virtual bool number_float(number_float_t val, const string_t& s) = 0; +``` + +A floating-point number was read. + +## Parameters + +`val` (in) +: floating-point value + +`s` (in) +: string representation of the original input + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/number_float/index.html b/api/json_sax/number_float/index.html index 1b6d3c811..ca8c2fbab 100644 --- a/api/json_sax/number_float/index.html +++ b/api/json_sax/number_float/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/number_float/index.md b/api/json_sax/number_float/index.md new file mode 100644 index 000000000..56c162d1c --- /dev/null +++ b/api/json_sax/number_float/index.md @@ -0,0 +1,203 @@ +# nlohmann::json_sax::number_float + +``` +virtual bool number_float(number_float_t val, const string_t& s) = 0; +``` + +A floating-point number was read. + +## Parameters + +`val` (in) : floating-point value + +`s` (in) : string representation of the original input + +## Return value + +Whether parsing should proceed. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/number_integer.md b/api/json_sax/number_integer.md new file mode 100644 index 000000000..5c3cb4f31 --- /dev/null +++ b/api/json_sax/number_integer.md @@ -0,0 +1,36 @@ +# nlohmann::json_sax::number_integer + +```cpp +virtual bool number_integer(number_integer_t val) = 0; +``` + +An integer number was read. + +## Parameters + +`val` (in) +: integer value + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/number_integer/index.html b/api/json_sax/number_integer/index.html index a6368f0a6..f76079b45 100644 --- a/api/json_sax/number_integer/index.html +++ b/api/json_sax/number_integer/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/number_integer/index.md b/api/json_sax/number_integer/index.md new file mode 100644 index 000000000..3f56aff31 --- /dev/null +++ b/api/json_sax/number_integer/index.md @@ -0,0 +1,201 @@ +# nlohmann::json_sax::number_integer + +``` +virtual bool number_integer(number_integer_t val) = 0; +``` + +An integer number was read. + +## Parameters + +`val` (in) : integer value + +## Return value + +Whether parsing should proceed. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/number_unsigned.md b/api/json_sax/number_unsigned.md new file mode 100644 index 000000000..0ac250037 --- /dev/null +++ b/api/json_sax/number_unsigned.md @@ -0,0 +1,36 @@ +# nlohmann::json_sax::number_unsigned + +```cpp +virtual bool number_unsigned(number_unsigned_t val) = 0; +``` + +An unsigned integer number was read. + +## Parameters + +`val` (in) +: unsigned integer value + +## Return value + +Whether parsing should proceed. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/number_unsigned/index.html b/api/json_sax/number_unsigned/index.html index 2acf9a8be..65dc341c9 100644 --- a/api/json_sax/number_unsigned/index.html +++ b/api/json_sax/number_unsigned/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/number_unsigned/index.md b/api/json_sax/number_unsigned/index.md new file mode 100644 index 000000000..d7c4495d2 --- /dev/null +++ b/api/json_sax/number_unsigned/index.md @@ -0,0 +1,201 @@ +# nlohmann::json_sax::number_unsigned + +``` +virtual bool number_unsigned(number_unsigned_t val) = 0; +``` + +An unsigned integer number was read. + +## Parameters + +`val` (in) : unsigned integer value + +## Return value + +Whether parsing should proceed. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/parse_error.md b/api/json_sax/parse_error.md new file mode 100644 index 000000000..e41cb67ff --- /dev/null +++ b/api/json_sax/parse_error.md @@ -0,0 +1,44 @@ +# nlohmann::json_sax::parse_error + +```cpp +virtual bool parse_error(std::size_t position, + const std::string& last_token, + const detail::exception& ex) = 0; +``` + +A parse error occurred. + +## Parameters + +`position` (in) +: the position in the input where the error occurs + +`last_token` (in) +: the last read token + +`ex` (in) +: an exception object describing the error + +## Return value + +Whether parsing should proceed (**must return `#!cpp false`**). + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/parse_error/index.html b/api/json_sax/parse_error/index.html index 69b229b59..6e79a0aa5 100644 --- a/api/json_sax/parse_error/index.html +++ b/api/json_sax/parse_error/index.html @@ -169,4 +169,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/parse_error/index.md b/api/json_sax/parse_error/index.md new file mode 100644 index 000000000..02d2d095b --- /dev/null +++ b/api/json_sax/parse_error/index.md @@ -0,0 +1,207 @@ +# nlohmann::json_sax::parse_error + +``` +virtual bool parse_error(std::size_t position, + const std::string& last_token, + const detail::exception& ex) = 0; +``` + +A parse error occurred. + +## Parameters + +`position` (in) : the position in the input where the error occurs + +`last_token` (in) : the last read token + +`ex` (in) : an exception object describing the error + +## Return value + +Whether parsing should proceed (**must return `false`**). + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/start_array.md b/api/json_sax/start_array.md new file mode 100644 index 000000000..1a221565f --- /dev/null +++ b/api/json_sax/start_array.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::start_array + +```cpp +virtual bool start_array(std::size_t elements) = 0; +``` + +The beginning of an array was read. + +## Parameters + +`elements` (in) +: number of array elements, or `#!cpp std::numeric_limits::max()` if unknown + +## Return value + +Whether parsing should proceed. + +## Notes + +Binary formats may report the number of elements. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/start_array/index.html b/api/json_sax/start_array/index.html index eca99c626..47139cfcb 100644 --- a/api/json_sax/start_array/index.html +++ b/api/json_sax/start_array/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/start_array/index.md b/api/json_sax/start_array/index.md new file mode 100644 index 000000000..b9e5f2916 --- /dev/null +++ b/api/json_sax/start_array/index.md @@ -0,0 +1,205 @@ +# nlohmann::json_sax::start_array + +``` +virtual bool start_array(std::size_t elements) = 0; +``` + +The beginning of an array was read. + +## Parameters + +`elements` (in) : number of array elements, or `std::numeric_limits::max()` if unknown + +## Return value + +Whether parsing should proceed. + +## Notes + +Binary formats may report the number of elements. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/start_object.md b/api/json_sax/start_object.md new file mode 100644 index 000000000..5ae753805 --- /dev/null +++ b/api/json_sax/start_object.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::start_object + +```cpp +virtual bool start_object(std::size_t elements) = 0; +``` + +The beginning of an object was read. + +## Parameters + +`elements` (in) +: number of object elements, or `#!cpp std::numeric_limits::max()` if unknown + +## Return value + +Whether parsing should proceed. + +## Notes + +Binary formats may report the number of elements. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/start_object/index.html b/api/json_sax/start_object/index.html index 43263ee87..2e6ca940d 100644 --- a/api/json_sax/start_object/index.html +++ b/api/json_sax/start_object/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/start_object/index.md b/api/json_sax/start_object/index.md new file mode 100644 index 000000000..48430be49 --- /dev/null +++ b/api/json_sax/start_object/index.md @@ -0,0 +1,205 @@ +# nlohmann::json_sax::start_object + +``` +virtual bool start_object(std::size_t elements) = 0; +``` + +The beginning of an object was read. + +## Parameters + +`elements` (in) : number of object elements, or `std::numeric_limits::max()` if unknown + +## Return value + +Whether parsing should proceed. + +## Notes + +Binary formats may report the number of elements. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/string.md b/api/json_sax/string.md new file mode 100644 index 000000000..dcffb5f61 --- /dev/null +++ b/api/json_sax/string.md @@ -0,0 +1,40 @@ +# nlohmann::json_sax::string + +```cpp +virtual bool string(string_t& val) = 0; +``` + +A string value was read. + +## Parameters + +`val` (in) +: string value + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed string value. + +## Examples + +??? example + + The example below shows how the SAX interface is used. + + ```cpp + --8<-- "examples/sax_parse.cpp" + ``` + + Output: + + ```json + --8<-- "examples/sax_parse.output" + ``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/json_sax/string/index.html b/api/json_sax/string/index.html index 427571689..abe4a0067 100644 --- a/api/json_sax/string/index.html +++ b/api/json_sax/string/index.html @@ -167,4 +167,4 @@ ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) result: false -

Version history

  • Added in version 3.2.0.
\ No newline at end of file +

Version history

  • Added in version 3.2.0.
\ No newline at end of file diff --git a/api/json_sax/string/index.md b/api/json_sax/string/index.md new file mode 100644 index 000000000..d05dc4e9a --- /dev/null +++ b/api/json_sax/string/index.md @@ -0,0 +1,205 @@ +# nlohmann::json_sax::string + +``` +virtual bool string(string_t& val) = 0; +``` + +A string value was read. + +## Parameters + +`val` (in) : string value + +## Return value + +Whether parsing should proceed. + +## Notes + +It is safe to move the passed string value. + +## Examples + +Example + +The example below shows how the SAX interface is used. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +// a simple event consumer that collects string representations of the passed +// values; note inheriting from json::json_sax_t is not required, but can +// help not to forget a required function +class sax_event_consumer : public json::json_sax_t +{ + public: + std::vector events; + + bool null() override + { + events.push_back("null()"); + return true; + } + + bool boolean(bool val) override + { + events.push_back("boolean(val=" + std::string(val ? "true" : "false") + ")"); + return true; + } + + bool number_integer(number_integer_t val) override + { + events.push_back("number_integer(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_unsigned(number_unsigned_t val) override + { + events.push_back("number_unsigned(val=" + std::to_string(val) + ")"); + return true; + } + + bool number_float(number_float_t val, const string_t& s) override + { + events.push_back("number_float(val=" + std::to_string(val) + ", s=" + s + ")"); + return true; + } + + bool string(string_t& val) override + { + events.push_back("string(val=" + val + ")"); + return true; + } + + bool start_object(std::size_t elements) override + { + events.push_back("start_object(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_object() override + { + events.push_back("end_object()"); + return true; + } + + bool start_array(std::size_t elements) override + { + events.push_back("start_array(elements=" + std::to_string(elements) + ")"); + return true; + } + + bool end_array() override + { + events.push_back("end_array()"); + return true; + } + + bool key(string_t& val) override + { + events.push_back("key(val=" + val + ")"); + return true; + } + + bool binary(json::binary_t& val) override + { + events.push_back("binary(val=[...])"); + return true; + } + + bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex) override + { + events.push_back("parse_error(position=" + std::to_string(position) + ", last_token=" + last_token + ",\n ex=" + std::string(ex.what()) + ")"); + return false; + } +}; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, -38793], + "DeletionDate": null, + "Distance": 12.723374634 + } + }] + )"; + + // create a SAX event consumer object + sax_event_consumer sec; + + // parse JSON + bool result = json::sax_parse(text, &sec); + + // output the recorded events + for (auto& event : sec.events) + { + std::cout << event << "\n"; + } + + // output the result of sax_parse + std::cout << "\nresult: " << std::boolalpha << result << std::endl; +} +``` + +Output: + +``` +start_object(elements=18446744073709551615) +key(val=Image) +start_object(elements=18446744073709551615) +key(val=Width) +number_unsigned(val=800) +key(val=Height) +number_unsigned(val=600) +key(val=Title) +string(val=View from 15th Floor) +key(val=Thumbnail) +start_object(elements=18446744073709551615) +key(val=Url) +string(val=http://www.example.com/image/481989943) +key(val=Height) +number_unsigned(val=125) +key(val=Width) +number_unsigned(val=100) +end_object() +key(val=Animated) +boolean(val=false) +key(val=IDs) +start_array(elements=18446744073709551615) +number_unsigned(val=116) +number_unsigned(val=943) +number_unsigned(val=234) +number_integer(val=-38793) +end_array() +key(val=DeletionDate) +null() +key(val=Distance) +number_float(val=12.723375, s=12.723374634) +end_object() +end_object() +parse_error(position=460, last_token=12.723374634 } }], + ex=[json.exception.parse_error.101] parse error at line 17, column 6: syntax error while parsing value - unexpected ']'; expected end of input) + +result: false +``` + +## Version history + +- Added in version 3.2.0. diff --git a/api/macros.md b/api/macros.md new file mode 100644 index 000000000..507c04932 --- /dev/null +++ b/api/macros.md @@ -0,0 +1,111 @@ +# Macros + +Some aspects of the library can be configured by defining preprocessor macros **before** including the `json.hpp` +header. See also the [macro overview page](../../features/macros.md). + +## Runtime assertions + +- [**JSON_ASSERT(x)**](json_assert.md) - control behavior of runtime assertions + +## Exceptions + +- [**JSON_CATCH_USER(exception)**
**JSON_THROW_USER(exception)**
**JSON_TRY_USER**](json_throw_user.md) - control exceptions +- [**JSON_DIAGNOSTICS**](json_diagnostics.md) - control extended diagnostics +- [**JSON_DIAGNOSTIC_POSITIONS**](json_diagnostic_positions.md) - access positions of elements +- [**JSON_NOEXCEPTION**](json_noexception.md) - switch off exceptions + +## Language support + +- [**JSON_HAS_CPP_11**
**JSON_HAS_CPP_14**
**JSON_HAS_CPP_17**
**JSON_HAS_CPP_20**](json_has_cpp_11.md) - set supported C++ standard +- [**JSON_HAS_FILESYSTEM**
**JSON_HAS_EXPERIMENTAL_FILESYSTEM**](json_has_filesystem.md) - control `std::filesystem` support +- [**JSON_HAS_RANGES**](json_has_ranges.md) - control `std::ranges` support +- [**JSON_HAS_STD_FORMAT**](json_has_std_format.md) - control `std::format`/`std::formatter` support +- [**JSON_HAS_THREE_WAY_COMPARISON**](json_has_three_way_comparison.md) - control 3-way comparison support +- [**JSON_NO_IO**](json_no_io.md) - switch off functions relying on certain C++ I/O headers +- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers +- [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace + +## Library version + +- [**JSON_SKIP_LIBRARY_VERSION_CHECK**](json_skip_library_version_check.md) - skip library version check +- [**NLOHMANN_JSON_VERSION_MAJOR**
**NLOHMANN_JSON_VERSION_MINOR**
**NLOHMANN_JSON_VERSION_PATCH**](nlohmann_json_version_major.md) + \- library version information + +## Library namespace + +- [**NLOHMANN_JSON_NAMESPACE**](nlohmann_json_namespace.md) - full name of the `nlohmann` namespace +- [**NLOHMANN_JSON_NAMESPACE_BEGIN**
**NLOHMANN_JSON_NAMESPACE_END**](nlohmann_json_namespace_begin.md) - open and + close the library namespace +- [**NLOHMANN_JSON_NAMESPACE_NO_VERSION**](nlohmann_json_namespace_no_version.md) - disable the version component of + the inline namespace + +## Type conversions + +- [**JSON_BRACE_INIT_COPY_SEMANTICS**](json_brace_init_copy_semantics.md) - opt in to copy/move semantics for single-element brace initialization +- [**JSON_DISABLE_ENUM_SERIALIZATION**](json_disable_enum_serialization.md) - switch off default serialization/deserialization functions for enums +- [**JSON_USE_IMPLICIT_CONVERSIONS**](json_use_implicit_conversions.md) - control implicit conversions + +## Comparison behavior + +- [**JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON**](json_use_legacy_discarded_value_comparison.md) - + control comparison of discarded values + +## Serialization/deserialization macros + +### Enums + +- [**NLOHMANN_JSON_SERIALIZE_ENUM**](nlohmann_json_serialize_enum.md) - serialize/deserialize an enum +- [**NLOHMANN_JSON_SERIALIZE_ENUM_STRICT**](nlohmann_json_serialize_enum_strict.md) - serialize/deserialize an enum with exceptions + +### Classes and structs + +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE**](nlohmann_define_type_intrusive.md) - serialize/deserialize a non-derived class + with private members +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT**](nlohmann_define_type_intrusive.md) - serialize/deserialize a + non-derived class with private members; uses default values +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE**](nlohmann_define_type_intrusive.md) - serialize a non-derived class + with private members +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE**](nlohmann_define_type_non_intrusive.md) - serialize/deserialize a non-derived + class +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](nlohmann_define_type_non_intrusive.md) - serialize/deserialize a + non-derived class; uses default values +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](nlohmann_define_type_non_intrusive.md) - serialize a + non-derived class + +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE**](nlohmann_define_derived_type.md) - serialize/deserialize a derived class + with private members +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT**](nlohmann_define_derived_type.md) - serialize/deserialize a + derived class with private members; uses default values +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE**](nlohmann_define_derived_type.md) - serialize a derived + class with private members +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE**](nlohmann_define_derived_type.md) - serialize/deserialize a derived + class +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](nlohmann_define_derived_type.md) - serialize/deserialize + a derived class; uses default values +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](nlohmann_define_derived_type.md) - serialize a derived + class +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize a non-derived class + with private members; uses custom names +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize a + non-derived class with private members; uses default values; uses custom names +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize a non-derived class + with private members; uses custom names +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize a non-derived + class; uses custom names +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize a + non-derived class; uses default values; uses custom names +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize a + non-derived class; uses custom names + +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize a derived class + with private members; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize a + derived class with private members; uses default values; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize a derived + class with private members; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize a derived + class; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize/deserialize + a derived class; uses default values; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](nlohmann_define_type_with_names.md) - serialize a derived + class; uses custom names \ No newline at end of file diff --git a/api/macros/index.html b/api/macros/index.html index 1c01f90af..be95da378 100644 --- a/api/macros/index.html +++ b/api/macros/index.html @@ -1 +1 @@ - Overview - JSON for Modern C++

Macros

Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the macro overview page.

Runtime assertions

Exceptions

Language support

Library version

Library namespace

Type conversions

Comparison behavior

Serialization/deserialization macros

Enums

Classes and structs

\ No newline at end of file + Overview - JSON for Modern C++

Macros

Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the macro overview page.

Runtime assertions

Exceptions

Language support

Library version

Library namespace

Type conversions

Comparison behavior

Serialization/deserialization macros

Enums

Classes and structs

\ No newline at end of file diff --git a/api/macros/index.md b/api/macros/index.md new file mode 100644 index 000000000..cd9ea0a09 --- /dev/null +++ b/api/macros/index.md @@ -0,0 +1,90 @@ +# Macros + +Some aspects of the library can be configured by defining preprocessor macros **before** including the `json.hpp` header. See also the [macro overview page](https://json.nlohmann.me/features/macros/index.md). + +## Runtime assertions + +- [**JSON_ASSERT(x)**](https://json.nlohmann.me/api/macros/json_assert/index.md) - control behavior of runtime assertions + +## Exceptions + +- [**JSON_CATCH_USER(exception)**\ + **JSON_THROW_USER(exception)**\ + **JSON_TRY_USER**](https://json.nlohmann.me/api/macros/json_throw_user/index.md) - control exceptions +- [**JSON_DIAGNOSTICS**](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) - control extended diagnostics +- [**JSON_DIAGNOSTIC_POSITIONS**](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) - access positions of elements +- [**JSON_NOEXCEPTION**](https://json.nlohmann.me/api/macros/json_noexception/index.md) - switch off exceptions + +## Language support + +- [**JSON_HAS_CPP_11**\ + **JSON_HAS_CPP_14**\ + **JSON_HAS_CPP_17**\ + **JSON_HAS_CPP_20**](https://json.nlohmann.me/api/macros/json_has_cpp_11/index.md) - set supported C++ standard +- [**JSON_HAS_FILESYSTEM**\ + **JSON_HAS_EXPERIMENTAL_FILESYSTEM**](https://json.nlohmann.me/api/macros/json_has_filesystem/index.md) - control `std::filesystem` support +- [**JSON_HAS_RANGES**](https://json.nlohmann.me/api/macros/json_has_ranges/index.md) - control `std::ranges` support +- [**JSON_HAS_STD_FORMAT**](https://json.nlohmann.me/api/macros/json_has_std_format/index.md) - control `std::format`/`std::formatter` support +- [**JSON_HAS_THREE_WAY_COMPARISON**](https://json.nlohmann.me/api/macros/json_has_three_way_comparison/index.md) - control 3-way comparison support +- [**JSON_NO_IO**](https://json.nlohmann.me/api/macros/json_no_io/index.md) - switch off functions relying on certain C++ I/O headers +- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](https://json.nlohmann.me/api/macros/json_skip_unsupported_compiler_check/index.md) - do not warn about unsupported compilers +- [**JSON_USE_GLOBAL_UDLS**](https://json.nlohmann.me/api/macros/json_use_global_udls/index.md) - place user-defined string literals (UDLs) into the global namespace + +## Library version + +- [**JSON_SKIP_LIBRARY_VERSION_CHECK**](https://json.nlohmann.me/api/macros/json_skip_library_version_check/index.md) - skip library version check +- [**NLOHMANN_JSON_VERSION_MAJOR**\ + **NLOHMANN_JSON_VERSION_MINOR**\ + **NLOHMANN_JSON_VERSION_PATCH**](https://json.nlohmann.me/api/macros/nlohmann_json_version_major/index.md) + - library version information + +## Library namespace + +- [**NLOHMANN_JSON_NAMESPACE**](https://json.nlohmann.me/api/macros/nlohmann_json_namespace/index.md) - full name of the `nlohmann` namespace +- [**NLOHMANN_JSON_NAMESPACE_BEGIN**\ + **NLOHMANN_JSON_NAMESPACE_END**](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/index.md) - open and close the library namespace +- [**NLOHMANN_JSON_NAMESPACE_NO_VERSION**](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/index.md) - disable the version component of the inline namespace + +## Type conversions + +- [**JSON_BRACE_INIT_COPY_SEMANTICS**](https://json.nlohmann.me/api/macros/json_brace_init_copy_semantics/index.md) - opt in to copy/move semantics for single-element brace initialization +- [**JSON_DISABLE_ENUM_SERIALIZATION**](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md) - switch off default serialization/deserialization functions for enums +- [**JSON_USE_IMPLICIT_CONVERSIONS**](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) - control implicit conversions + +## Comparison behavior + +- [**JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON**](https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/index.md) - control comparison of discarded values + +## Serialization/deserialization macros + +### Enums + +- [**NLOHMANN_JSON_SERIALIZE_ENUM**](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) - serialize/deserialize an enum +- [**NLOHMANN_JSON_SERIALIZE_ENUM_STRICT**](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/index.md) - serialize/deserialize an enum with exceptions + +### Classes and structs + +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) - serialize/deserialize a non-derived class with private members +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) - serialize/deserialize a non-derived class with private members; uses default values +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) - serialize a non-derived class with private members +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) - serialize/deserialize a non-derived class +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) - serialize/deserialize a non-derived class; uses default values +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) - serialize a non-derived class +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) - serialize/deserialize a derived class with private members +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) - serialize/deserialize a derived class with private members; uses default values +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) - serialize a derived class with private members +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) - serialize/deserialize a derived class +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) - serialize/deserialize a derived class; uses default values +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) - serialize a derived class +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a non-derived class with private members; uses custom names +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a non-derived class with private members; uses default values; uses custom names +- [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize a non-derived class with private members; uses custom names +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a non-derived class; uses custom names +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a non-derived class; uses default values; uses custom names +- [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize a non-derived class; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a derived class with private members; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a derived class with private members; uses default values; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize a derived class with private members; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a derived class; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize/deserialize a derived class; uses default values; uses custom names +- [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES**](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) - serialize a derived class; uses custom names diff --git a/api/macros/json_assert.md b/api/macros/json_assert.md new file mode 100644 index 000000000..2d7b0c78a --- /dev/null +++ b/api/macros/json_assert.md @@ -0,0 +1,88 @@ +# JSON_ASSERT + +```cpp +#define JSON_ASSERT(x) /* value */ +``` + +This macro controls which code is executed for [runtime assertions](../../features/assertions.md) of the library. + +## Parameters + +`x` (in) +: expression of a scalar type + +## Default definition + +The default value is [`#!cpp assert(x)`](https://en.cppreference.com/w/cpp/error/assert). + +```cpp +#define JSON_ASSERT(x) assert(x) +``` + +Therefore, assertions can be switched off by defining `NDEBUG`. + +## Notes + +- The library uses numerous assertions to guarantee invariants and to abort in case of otherwise undefined behavior + (e.g., when calling [operator[]](../basic_json/operator%5B%5D.md) with a missing object key on a `const` object). See + page [runtime assertions](../../features/assertions.md) for more information. +- Defining the macro to code that does not call `std::abort` may leave the library in an undefined state. +- The macro is undefined outside the library. + +## Examples + +??? example "Example 1: default behavior" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + const json j = {{"key", "value"}}; + auto v = j["missing"]; + } + ``` + + Output: + + ``` + Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144. + ``` + +??? example "Example 2: user-defined behavior" + + The assertion reporting can be changed by defining `JSON_ASSERT(x)` differently. + + ```cpp + #include + #include + #define JSON_ASSERT(x) if(!(x)){fprintf(stderr, "assertion error in %s\n", __FUNCTION__); std::abort();} + + #include + + using json = nlohmann::json; + + int main() + { + const json j = {{"key", "value"}}; + auto v = j["missing"]; + } + ``` + + Output: + + ``` + assertion error in operator[] + ``` + +## See also + +- [Runtime Assertions](../../features/assertions.md) - overview documentation + +## Version history + +- Added in version 3.9.0. diff --git a/api/macros/json_assert/index.html b/api/macros/json_assert/index.html index bde13b5ee..ddbec394e 100644 --- a/api/macros/json_assert/index.html +++ b/api/macros/json_assert/index.html @@ -24,4 +24,4 @@ auto v = j["missing"]; }

Output:

assertion error in operator[]
-

See also

Version history

  • Added in version 3.9.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.9.0.
\ No newline at end of file diff --git a/api/macros/json_assert/index.md b/api/macros/json_assert/index.md new file mode 100644 index 000000000..fd76aad66 --- /dev/null +++ b/api/macros/json_assert/index.md @@ -0,0 +1,85 @@ +# JSON_ASSERT + +``` +#define JSON_ASSERT(x) /* value */ +``` + +This macro controls which code is executed for [runtime assertions](https://json.nlohmann.me/features/assertions/index.md) of the library. + +## Parameters + +`x` (in) : expression of a scalar type + +## Default definition + +The default value is [`assert(x)`](https://en.cppreference.com/w/cpp/error/assert). + +``` +#define JSON_ASSERT(x) assert(x) +``` + +Therefore, assertions can be switched off by defining `NDEBUG`. + +## Notes + +- The library uses numerous assertions to guarantee invariants and to abort in case of otherwise undefined behavior (e.g., when calling [operator[]](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) with a missing object key on a `const` object). See page [runtime assertions](https://json.nlohmann.me/features/assertions/index.md) for more information. +- Defining the macro to code that does not call `std::abort` may leave the library in an undefined state. +- The macro is undefined outside the library. + +## Examples + +Example 1: default behavior + +The following code will trigger an assertion at runtime: + +``` +#include + +using json = nlohmann::json; + +int main() +{ + const json j = {{"key", "value"}}; + auto v = j["missing"]; +} +``` + +Output: + +``` +Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144. +``` + +Example 2: user-defined behavior + +The assertion reporting can be changed by defining `JSON_ASSERT(x)` differently. + +``` +#include +#include +#define JSON_ASSERT(x) if(!(x)){fprintf(stderr, "assertion error in %s\n", __FUNCTION__); std::abort();} + +#include + +using json = nlohmann::json; + +int main() +{ + const json j = {{"key", "value"}}; + auto v = j["missing"]; +} +``` + +Output: + +``` +assertion error in operator[] +``` + +## See also + +- [Runtime Assertions](https://json.nlohmann.me/features/assertions/index.md) - overview documentation + +## Version history + +- Added in version 3.9.0. diff --git a/api/macros/json_brace_init_copy_semantics.md b/api/macros/json_brace_init_copy_semantics.md new file mode 100644 index 000000000..b821a046d --- /dev/null +++ b/api/macros/json_brace_init_copy_semantics.md @@ -0,0 +1,95 @@ +# JSON_BRACE_INIT_COPY_SEMANTICS + +```cpp +#define JSON_BRACE_INIT_COPY_SEMANTICS /* value */ +``` + +When defined to `1`, single-element brace initialization of a `basic_json` value is treated as a copy/move of the +element rather than wrapping it in a single-element array. + +## Default definition + +The default value is `0` (disabled — existing behavior is preserved). + +```cpp +#define JSON_BRACE_INIT_COPY_SEMANTICS 0 +``` + +## Notes + +!!! note "Background" + + C++ always prefers the `initializer_list` constructor over the copy/move constructor for brace initialization. This + means that code like + + ```cpp + json obj = {{"key", "value"}}; + json j{obj}; + ``` + + creates a single-element **array** `[{"key":"value"}]` instead of a copy of `obj`. This behavior is + compiler-dependent for older compilers (GCC wrapped, Clang did not), but starting from Clang 20, both compilers + behave the same way. + + Enabling this macro opts into copy/move semantics for this case + (see [#5074](https://github.com/nlohmann/json/issues/5074)). + +!!! warning "Opt-in only" + + This macro must be defined **before** including ``. Defining it after the include has no effect. + +!!! tip "Workaround without the macro" + + To explicitly create a single-element array without enabling this macro, use `json::array()`: + + ```cpp + json j = json::array({obj}); // always creates [obj] + ``` + +## Examples + +??? example "Default behavior (macro not defined)" + + Without the macro, single-element brace initialization wraps the value in an array: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + json obj = {{"key", "value"}}; + + json j{obj}; + // j is [{"key":"value"}] -- single-element array, NOT a copy of obj + } + ``` + +??? example "Opt-in copy semantics (macro defined to 1)" + + With the macro, single-element brace initialization copies/moves the value: + + ```cpp + #define JSON_BRACE_INIT_COPY_SEMANTICS 1 + #include + + using json = nlohmann::json; + + int main() + { + json obj = {{"key", "value"}}; + + json j{obj}; + // j is {"key":"value"} -- copy of obj + } + ``` + +## See also + +- [FAQ: Brace initialization yields arrays](../../home/faq.md#brace-initialization-yields-arrays) +- [**basic_json(initializer_list_t)**](../basic_json/basic_json.md) - the affected constructor + +## Version history + +- Added in version 3.12.x. diff --git a/api/macros/json_brace_init_copy_semantics/index.html b/api/macros/json_brace_init_copy_semantics/index.html index 552ce0309..410744ac5 100644 --- a/api/macros/json_brace_init_copy_semantics/index.html +++ b/api/macros/json_brace_init_copy_semantics/index.html @@ -26,4 +26,4 @@ json j{obj}; // j is {"key":"value"} -- copy of obj } -

See also

Version history

  • Added in version 3.12.x.
\ No newline at end of file +

See also

Version history

  • Added in version 3.12.x.
\ No newline at end of file diff --git a/api/macros/json_brace_init_copy_semantics/index.md b/api/macros/json_brace_init_copy_semantics/index.md new file mode 100644 index 000000000..60506037f --- /dev/null +++ b/api/macros/json_brace_init_copy_semantics/index.md @@ -0,0 +1,90 @@ +# JSON_BRACE_INIT_COPY_SEMANTICS + +``` +#define JSON_BRACE_INIT_COPY_SEMANTICS /* value */ +``` + +When defined to `1`, single-element brace initialization of a `basic_json` value is treated as a copy/move of the element rather than wrapping it in a single-element array. + +## Default definition + +The default value is `0` (disabled — existing behavior is preserved). + +``` +#define JSON_BRACE_INIT_COPY_SEMANTICS 0 +``` + +## Notes + +Background + +C++ always prefers the `initializer_list` constructor over the copy/move constructor for brace initialization. This means that code like + +``` +json obj = {{"key", "value"}}; +json j{obj}; +``` + +creates a single-element **array** `[{"key":"value"}]` instead of a copy of `obj`. This behavior is compiler-dependent for older compilers (GCC wrapped, Clang did not), but starting from Clang 20, both compilers behave the same way. + +Enabling this macro opts into copy/move semantics for this case (see [#5074](https://github.com/nlohmann/json/issues/5074)). + +Opt-in only + +This macro must be defined **before** including ``. Defining it after the include has no effect. + +Workaround without the macro + +To explicitly create a single-element array without enabling this macro, use `json::array()`: + +``` +json j = json::array({obj}); // always creates [obj] +``` + +## Examples + +Default behavior (macro not defined) + +Without the macro, single-element brace initialization wraps the value in an array: + +``` +#include + +using json = nlohmann::json; + +int main() +{ + json obj = {{"key", "value"}}; + + json j{obj}; + // j is [{"key":"value"}] -- single-element array, NOT a copy of obj +} +``` + +Opt-in copy semantics (macro defined to 1) + +With the macro, single-element brace initialization copies/moves the value: + +``` +#define JSON_BRACE_INIT_COPY_SEMANTICS 1 +#include + +using json = nlohmann::json; + +int main() +{ + json obj = {{"key", "value"}}; + + json j{obj}; + // j is {"key":"value"} -- copy of obj +} +``` + +## See also + +- [FAQ: Brace initialization yields arrays](https://json.nlohmann.me/home/faq/#brace-initialization-yields-arrays) +- [**basic_json(initializer_list_t)**](https://json.nlohmann.me/api/basic_json/basic_json/index.md) - the affected constructor + +## Version history + +- Added in version 3.12.x. diff --git a/api/macros/json_diagnostic_positions.md b/api/macros/json_diagnostic_positions.md new file mode 100644 index 000000000..f928f227e --- /dev/null +++ b/api/macros/json_diagnostic_positions.md @@ -0,0 +1,119 @@ +# JSON_DIAGNOSTIC_POSITIONS + +```cpp +#define JSON_DIAGNOSTIC_POSITIONS /* value */ +``` + +This macro enables position diagnostics for generated JSON objects. + +When enabled, two new member functions [`start_pos()`](../basic_json/start_pos.md) and +[`end_pos()`](../basic_json/end_pos.md) are added to [`basic_json`](../basic_json/index.md) values. If the value was +created by calling the[`parse`](../basic_json/parse.md) function, then these functions allow querying the byte positions +of the value in the input it was parsed from. In case the value was constructed by other means, `std::string::npos` is +returned. + +[`start_pos()`](../basic_json/start_pos.md) returns the position of the first character of a given value in the original +JSON string, while [`end_pos()`](../basic_json/end_pos.md) returns the position of the character _following_ the last +character. For objects and arrays, the first and last characters correspond to the opening or closing braces/brackets, +respectively. For primitive values, the first and last character represents the opening and closing quotes (strings) or +the first and last character of the field's numerical or predefined value (`true`, `false`, `null`), respectively. + +| JSON type | return value [`start_pos()`](../basic_json/start_pos.md) | return value [`end_pos()`](../basic_json/end_pos.md) | +|-----------|----------------------------------------------------------|------------------------------------------------------| +| object | position of the opening `{` | position after the closing `}` | +| array | position of the opening `[` | position after the closing `]` | +| string | position of the opening `"` | position after the closing `"` | +| number | position of the first character | position after the last character | +| boolean | position of `t` for `true` and `f` for `false` | position after `e` | +| null | position of `n` | position after `l` | + +Given the above, [`end_pos()`](../basic_json/end_pos.md)` - `[`start_pos()`](../basic_json/start_pos.md) for a JSON +value provides the length of the parsed JSON string for that value, including the opening or closing braces, brackets, +or quotes. + +Note that enabling this macro increases the size of every JSON value by two `std::size_t` fields and adds slight runtime +overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions. It also causes +these values to be reported in those error messages. + +## Default definition + +The default value is `0` (position diagnostics are switched off). + +```cpp +#define JSON_DIAGNOSTIC_POSITIONS 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! note "CMake option" + + Diagnostic positions can also be controlled with the CMake option + [`JSON_Diagnostic_Positions`](../../integration/cmake.md#json_diagnostic_positions) (`OFF` by default) + which defines `JSON_DIAGNOSTIC_POSITIONS` accordingly. + +!!! note "Availability" + + Diagnostic positions are only available if the value was created by the [`parse`](../basic_json/parse.md) function. + The [`sax_parse`](../basic_json/sax_parse.md) function or all other means to create a JSON value **do not** set the + diagnostic positions and [`start_pos()`](../basic_json/start_pos.md) and [`end_pos()`](../basic_json/end_pos.md) + will only return `std::string::npos` for these values. + +!!! warning "Invalidation" + + The returned positions are only valid as long as the JSON value is not changed. The positions are *not* updated + when the JSON value is changed. + +## Examples + +??? example "Example: retrieving positions" + + ```cpp + --8<-- "examples/diagnostic_positions.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostic_positions.output" + ``` + + The output shows the start/end positions of all the objects and fields in the JSON string. + +??? example "Example 2: using only diagnostic positions in exceptions" + + ```cpp + --8<-- "examples/diagnostic_positions_exception.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostic_positions_exception.output" + ``` + + The output shows the exception with start/end positions only. + +??? example "Example 3: using extended diagnostics with positions enabled in exceptions" + + ```cpp + --8<-- "examples/diagnostics_extended_positions.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_extended_positions.output" + ``` + + The output shows the exception with diagnostic path info and start/end positions. + +## See also + +- [:simple-cmake: JSON_Diagnostic_Positions](../../integration/cmake.md#json_diagnostic_positions) - CMake option to control the macro +- [JSON_DIAGNOSTICS](json_diagnostics.md) - macro to control extended diagnostics + +## Version history + +- Added in version 3.12.0. diff --git a/api/macros/json_diagnostic_positions/index.html b/api/macros/json_diagnostic_positions/index.html index acef90fae..6d63c2214 100644 --- a/api/macros/json_diagnostic_positions/index.html +++ b/api/macros/json_diagnostic_positions/index.html @@ -165,4 +165,4 @@ Parsed string: }

Output:

[json.exception.type_error.302] (/address/housenumber) (bytes 92-95) type must be number, but is string
 
The output shows the exception with diagnostic path info and start/end positions.
-

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.12.0.
\ No newline at end of file diff --git a/api/macros/json_diagnostic_positions/index.md b/api/macros/json_diagnostic_positions/index.md new file mode 100644 index 000000000..c8b110ae8 --- /dev/null +++ b/api/macros/json_diagnostic_positions/index.md @@ -0,0 +1,262 @@ +# JSON_DIAGNOSTIC_POSITIONS + +``` +#define JSON_DIAGNOSTIC_POSITIONS /* value */ +``` + +This macro enables position diagnostics for generated JSON objects. + +When enabled, two new member functions [`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) and [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md) are added to [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) values. If the value was created by calling the[`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function, then these functions allow querying the byte positions of the value in the input it was parsed from. In case the value was constructed by other means, `std::string::npos` is returned. + +[`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) returns the position of the first character of a given value in the original JSON string, while [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md) returns the position of the character *following* the last character. For objects and arrays, the first and last characters correspond to the opening or closing braces/brackets, respectively. For primitive values, the first and last character represents the opening and closing quotes (strings) or the first and last character of the field's numerical or predefined value (`true`, `false`, `null`), respectively. + +| JSON type | return value [`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) | return value [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md) | +| --------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| object | position of the opening `{` | position after the closing `}` | +| array | position of the opening `[` | position after the closing `]` | +| string | position of the opening `"` | position after the closing `"` | +| number | position of the first character | position after the last character | +| boolean | position of `t` for `true` and `f` for `false` | position after `e` | +| null | position of `n` | position after `l` | + +Given the above, [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md)`-`[`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) for a JSON value provides the length of the parsed JSON string for that value, including the opening or closing braces, brackets, or quotes. + +Note that enabling this macro increases the size of every JSON value by two `std::size_t` fields and adds slight runtime overhead to parsing, copying JSON value objects, and the generation of error messages for exceptions. It also causes these values to be reported in those error messages. + +## Default definition + +The default value is `0` (position diagnostics are switched off). + +``` +#define JSON_DIAGNOSTIC_POSITIONS 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +CMake option + +Diagnostic positions can also be controlled with the CMake option [`JSON_Diagnostic_Positions`](https://json.nlohmann.me/integration/cmake/#json_diagnostic_positions) (`OFF` by default) which defines `JSON_DIAGNOSTIC_POSITIONS` accordingly. + +Availability + +Diagnostic positions are only available if the value was created by the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function. The [`sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) function or all other means to create a JSON value **do not** set the diagnostic positions and [`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) and [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md) will only return `std::string::npos` for these values. + +Invalidation + +The returned positions are only valid as long as the JSON value is not changed. The positions are *not* updated when the JSON value is changed. + +## Examples + +Example: retrieving positions + +``` +#include + +#define JSON_DIAGNOSTIC_POSITIONS 1 +#include + +using json = nlohmann::json; + +int main() +{ + std::string json_string = R"( + { + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } + )"; + json j = json::parse(json_string); + + std::cout << "Root diagnostic positions: \n"; + std::cout << "\tstart_pos: " << j.start_pos() << '\n'; + std::cout << "\tend_pos:" << j.end_pos() << "\n"; + std::cout << "Original string: \n"; + std::cout << "{\n \"address\": {\n \"street\": \"Fake Street\",\n \"housenumber\": 1\n }\n }" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j.start_pos(), j.end_pos() - j.start_pos()) << "\n\n"; + + std::cout << "address diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "{ \"street\": \"Fake Street\",\n \"housenumber\": 1\n }" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"].start_pos(), j["address"].end_pos() - j["address"].start_pos()) << "\n\n"; + + std::cout << "street diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"]["street"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"]["street"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "\"Fake Street\"" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"]["street"].start_pos(), j["address"]["street"].end_pos() - j["address"]["street"].start_pos()) << "\n\n"; + + std::cout << "housenumber diagnostic positions: \n"; + std::cout << "\tstart_pos:" << j["address"]["housenumber"].start_pos() << '\n'; + std::cout << "\tend_pos:" << j["address"]["housenumber"].end_pos() << "\n\n"; + std::cout << "Original string: \n"; + std::cout << "1" << "\n"; + std::cout << "Parsed string: \n"; + std::cout << json_string.substr(j["address"]["housenumber"].start_pos(), j["address"]["housenumber"].end_pos() - j["address"]["housenumber"].start_pos()) << "\n\n"; +} +``` + +Output: + +``` +Root diagnostic positions: + start_pos: 5 + end_pos:109 +Original string: +{ + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } +Parsed string: +{ + "address": { + "street": "Fake Street", + "housenumber": 1 + } + } + +address diagnostic positions: + start_pos:26 + end_pos:103 + +Original string: +{ "street": "Fake Street", + "housenumber": 1 + } +Parsed string: +{ + "street": "Fake Street", + "housenumber": 1 + } + +street diagnostic positions: + start_pos:50 + end_pos:63 + +Original string: +"Fake Street" +Parsed string: +"Fake Street" + +housenumber diagnostic positions: + start_pos:92 + end_pos:93 + +Original string: +1 +Parsed string: +1 +``` + +The output shows the start/end positions of all the objects and fields in the JSON string. + +Example 2: using only diagnostic positions in exceptions + +``` +#include + +#define JSON_DIAGNOSTIC_POSITIONS 1 +#include + +using json = nlohmann::json; + +/* Demonstration of type error exception with diagnostic positions support enabled */ +int main() +{ + //Invalid json string - housenumber type must be int instead of string + const std::string json_invalid_string = R"( + { + "address": { + "street": "Fake Street", + "housenumber": "1" + } + } + )"; + json j = json::parse(json_invalid_string); + try + { + int housenumber = j["address"]["housenumber"]; + std::cout << housenumber; + } + catch (const json::exception& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.type_error.302] (bytes 92-95) type must be number, but is string +``` + +``` +The output shows the exception with start/end positions only. +``` + +Example 3: using extended diagnostics with positions enabled in exceptions + +``` +#include + +#define JSON_DIAGNOSTICS 1 +#define JSON_DIAGNOSTIC_POSITIONS 1 +#include + +using json = nlohmann::json; + +/* Demonstration of type error exception with diagnostic positions support enabled */ +int main() +{ + //Invalid json string - housenumber type must be int instead of string + const std::string json_invalid_string = R"( + { + "address": { + "street": "Fake Street", + "housenumber": "1" + } + } + )"; + json j = json::parse(json_invalid_string); + try + { + int housenumber = j["address"]["housenumber"]; + std::cout << housenumber; + } + catch (const json::exception& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.type_error.302] (/address/housenumber) (bytes 92-95) type must be number, but is string +``` + +``` +The output shows the exception with diagnostic path info and start/end positions. +``` + +## See also + +- [JSON_Diagnostic_Positions](https://json.nlohmann.me/integration/cmake/#json_diagnostic_positions) - CMake option to control the macro +- [JSON_DIAGNOSTICS](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) - macro to control extended diagnostics + +## Version history + +- Added in version 3.12.0. diff --git a/api/macros/json_diagnostics.md b/api/macros/json_diagnostics.md new file mode 100644 index 000000000..91bdc1b39 --- /dev/null +++ b/api/macros/json_diagnostics.md @@ -0,0 +1,94 @@ +# JSON_DIAGNOSTICS + +```cpp +#define JSON_DIAGNOSTICS /* value */ +``` + +This macro enables [extended diagnostics for exception messages](../../home/exceptions.md#extended-diagnostic-messages). +Possible values are `1` to enable or `0` to disable (default). + +When enabled, exception messages contain a [JSON Pointer](../json_pointer/json_pointer.md) to the JSON value that +triggered the exception. Note that enabling this macro increases the size of every JSON value by one pointer and adds +some runtime overhead. + +## Default definition + +The default value is `0` (extended diagnostics are switched off). + +```cpp +#define JSON_DIAGNOSTICS 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! note "ABI compatibility" + + As of version 3.11.0, this macro is no longer required to be defined consistently throughout a codebase to avoid + One Definition Rule (ODR) violations, as the value of this macro is encoded in the namespace, resulting in distinct + symbol names. + + This allows different parts of a codebase to use different versions or configurations of this library without + causing improper behavior. + + Where possible, it is still recommended that all code define this the same way for maximum interoperability. + +!!! hint "CMake option" + + Diagnostic messages can also be controlled with the CMake option + [`JSON_Diagnostics`](../../integration/cmake.md#json_diagnostics) (`OFF` by default) + which defines `JSON_DIAGNOSTICS` accordingly. + +## Examples + +??? example "Example 1: default behavior" + + ```cpp + --8<-- "examples/diagnostics_standard.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_standard.output" + ``` + + This exception can be hard to debug if storing the value `#!c "12"` and accessing it is further apart. + +??? example "Example 2: extended diagnostic messages" + + ```cpp + --8<-- "examples/diagnostics_extended.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_extended.output" + ``` + + Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type. + +??? example "Example 3: using only diagnostic positions in exceptions" + + ```cpp + --8<-- "examples/diagnostic_positions_exception.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostic_positions_exception.output" + ``` + The output shows the exception with start/end positions only. + +## See also + +- [:simple-cmake: JSON_Diagnostics](../../integration/cmake.md#json_diagnostics) - CMake option to control the macro +- [JSON_DIAGNOSTIC_POSITIONS](json_diagnostic_positions.md) - macro to access positions of elements + +## Version history + +- Added in version 3.10.0. +- As of version 3.11.0, the definition is allowed to vary between translation units. diff --git a/api/macros/json_diagnostics/index.html b/api/macros/json_diagnostics/index.html index 4cd4ae1a7..71a4e9d3d 100644 --- a/api/macros/json_diagnostics/index.html +++ b/api/macros/json_diagnostics/index.html @@ -75,4 +75,4 @@ } }

Output:

[json.exception.type_error.302] (bytes 92-95) type must be number, but is string
-
The output shows the exception with start/end positions only.

See also

Version history

  • Added in version 3.10.0.
  • As of version 3.11.0, the definition is allowed to vary between translation units.
\ No newline at end of file + The output shows the exception with start/end positions only.

See also

Version history

  • Added in version 3.10.0.
  • As of version 3.11.0, the definition is allowed to vary between translation units.
\ No newline at end of file diff --git a/api/macros/json_diagnostics/index.md b/api/macros/json_diagnostics/index.md new file mode 100644 index 000000000..e8347e3b5 --- /dev/null +++ b/api/macros/json_diagnostics/index.md @@ -0,0 +1,156 @@ +# JSON_DIAGNOSTICS + +``` +#define JSON_DIAGNOSTICS /* value */ +``` + +This macro enables [extended diagnostics for exception messages](https://json.nlohmann.me/home/exceptions/#extended-diagnostic-messages). Possible values are `1` to enable or `0` to disable (default). + +When enabled, exception messages contain a [JSON Pointer](https://json.nlohmann.me/api/json_pointer/json_pointer/index.md) to the JSON value that triggered the exception. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead. + +## Default definition + +The default value is `0` (extended diagnostics are switched off). + +``` +#define JSON_DIAGNOSTICS 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +ABI compatibility + +As of version 3.11.0, this macro is no longer required to be defined consistently throughout a codebase to avoid One Definition Rule (ODR) violations, as the value of this macro is encoded in the namespace, resulting in distinct symbol names. + +This allows different parts of a codebase to use different versions or configurations of this library without causing improper behavior. + +Where possible, it is still recommended that all code define this the same way for maximum interoperability. + +CMake option + +Diagnostic messages can also be controlled with the CMake option [`JSON_Diagnostics`](https://json.nlohmann.me/integration/cmake/#json_diagnostics) (`OFF` by default) which defines `JSON_DIAGNOSTICS` accordingly. + +## Examples + +Example 1: default behavior + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j; + j["address"]["street"] = "Fake Street"; + j["address"]["housenumber"] = "12"; + + try + { + int housenumber = j["address"]["housenumber"]; + } + catch (const json::exception& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.type_error.302] type must be number, but is string +``` + +This exception can be hard to debug if storing the value `"12"` and accessing it is further apart. + +Example 2: extended diagnostic messages + +``` +#include + +# define JSON_DIAGNOSTICS 1 +#include + +using json = nlohmann::json; + +int main() +{ + json j; + j["address"]["street"] = "Fake Street"; + j["address"]["housenumber"] = "12"; + + try + { + int housenumber = j["address"]["housenumber"]; + } + catch (const json::exception& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.type_error.302] (/address/housenumber) type must be number, but is string +``` + +Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type. + +Example 3: using only diagnostic positions in exceptions + +``` +#include + +#define JSON_DIAGNOSTIC_POSITIONS 1 +#include + +using json = nlohmann::json; + +/* Demonstration of type error exception with diagnostic positions support enabled */ +int main() +{ + //Invalid json string - housenumber type must be int instead of string + const std::string json_invalid_string = R"( + { + "address": { + "street": "Fake Street", + "housenumber": "1" + } + } + )"; + json j = json::parse(json_invalid_string); + try + { + int housenumber = j["address"]["housenumber"]; + std::cout << housenumber; + } + catch (const json::exception& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.type_error.302] (bytes 92-95) type must be number, but is string +``` + +The output shows the exception with start/end positions only. + +## See also + +- [JSON_Diagnostics](https://json.nlohmann.me/integration/cmake/#json_diagnostics) - CMake option to control the macro +- [JSON_DIAGNOSTIC_POSITIONS](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) - macro to access positions of elements + +## Version history + +- Added in version 3.10.0. +- As of version 3.11.0, the definition is allowed to vary between translation units. diff --git a/api/macros/json_disable_enum_serialization.md b/api/macros/json_disable_enum_serialization.md new file mode 100644 index 000000000..2548a03fa --- /dev/null +++ b/api/macros/json_disable_enum_serialization.md @@ -0,0 +1,153 @@ +# JSON_DISABLE_ENUM_SERIALIZATION + +```cpp +#define JSON_DISABLE_ENUM_SERIALIZATION /* value */ +``` + +When defined to `1`, default serialization and deserialization functions for enums are excluded and have to be provided +by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) (see +[arbitrary type conversions](../../features/arbitrary_types.md) for more details). + +Parsing or serializing an enum will result in a compiler error. + +This works for both unscoped and scoped enums. + +## Default definition + +The default value is `0`. + +```cpp +#define JSON_DISABLE_ENUM_SERIALIZATION 0 +``` + +## Notes + +!!! hint "CMake option" + + Enum serialization can also be controlled with the CMake option + [`JSON_DisableEnumSerialization`](../../integration/cmake.md#json_disableenumserialization) + (`OFF` by default) which defines `JSON_DISABLE_ENUM_SERIALIZATION` accordingly. + +## Examples + +??? example "Example 1: Disabled behavior" + + The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, meaning the code below + **does not** compile. + + ```cpp + #define JSON_DISABLE_ENUM_SERIALIZATION 1 + #include + + using json = nlohmann::json; + + enum class Choice + { + first, + second, + }; + + int main() + { + // normally invokes to_json serialization function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not + const json j = Choice::first; + + // normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not + Choice ch = j.get(); + } + ``` + +??? example "Example 2: Serialize enum macro" + + The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses + [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) to parse and serialize the enum. + + ```cpp + #define JSON_DISABLE_ENUM_SERIALIZATION 1 + #include + + using json = nlohmann::json; + + enum class Choice + { + first, + second, + }; + + NLOHMANN_JSON_SERIALIZE_ENUM(Choice, + { + { Choice::first, "first" }, + { Choice::second, "second" }, + }) + + int main() + { + // uses user-defined to_json function defined by macro + const json j = Choice::first; + + // uses user-defined from_json function defined by macro + Choice ch = j.get(); + } + ``` + +??? example "Example 3: User-defined serialization/deserialization functions" + + The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses user-defined + functions to parse and serialize the enum. + + ```cpp + #define JSON_DISABLE_ENUM_SERIALIZATION 1 + #include + + using json = nlohmann::json; + + enum class Choice + { + first, + second, + }; + + void from_json(const json& j, Choice& ch) + { + auto value = j.get(); + if (value == "first") + { + ch = Choice::first; + } + else if (value == "second") + { + ch = Choice::second; + } + } + + void to_json(json& j, const Choice& ch) + { + if (ch == Choice::first) + { + j = "first"; + } + else if (ch == Choice::second) + { + j = "second"; + } + } + + int main() + { + // uses user-defined to_json function + const json j = Choice::first; + + // uses user-defined from_json function + Choice ch = j.get(); + } + ``` + +## See also + +- [:simple-cmake: JSON_DisableEnumSerialization](../../integration/cmake.md#json_disableenumserialization) - CMake option to control + the macro +- [`NLOHMANN_JSON_SERIALIZE_ENUM`](nlohmann_json_serialize_enum.md) - serialize/deserialize an enum + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_disable_enum_serialization/index.html b/api/macros/json_disable_enum_serialization/index.html index 81f7c5139..3dff8977b 100644 --- a/api/macros/json_disable_enum_serialization/index.html +++ b/api/macros/json_disable_enum_serialization/index.html @@ -88,4 +88,4 @@ // uses user-defined from_json function Choice ch = j.get<Choice>(); } -

See also

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/macros/json_disable_enum_serialization/index.md b/api/macros/json_disable_enum_serialization/index.md new file mode 100644 index 000000000..fe96f84db --- /dev/null +++ b/api/macros/json_disable_enum_serialization/index.md @@ -0,0 +1,145 @@ +# JSON_DISABLE_ENUM_SERIALIZATION + +``` +#define JSON_DISABLE_ENUM_SERIALIZATION /* value */ +``` + +When defined to `1`, default serialization and deserialization functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) (see [arbitrary type conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) for more details). + +Parsing or serializing an enum will result in a compiler error. + +This works for both unscoped and scoped enums. + +## Default definition + +The default value is `0`. + +``` +#define JSON_DISABLE_ENUM_SERIALIZATION 0 +``` + +## Notes + +CMake option + +Enum serialization can also be controlled with the CMake option [`JSON_DisableEnumSerialization`](https://json.nlohmann.me/integration/cmake/#json_disableenumserialization) (`OFF` by default) which defines `JSON_DISABLE_ENUM_SERIALIZATION` accordingly. + +## Examples + +Example 1: Disabled behavior + +The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, meaning the code below **does not** compile. + +``` +#define JSON_DISABLE_ENUM_SERIALIZATION 1 +#include + +using json = nlohmann::json; + +enum class Choice +{ + first, + second, +}; + +int main() +{ + // normally invokes to_json serialization function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not + const json j = Choice::first; + + // normally invokes from_json parse function but with JSON_DISABLE_ENUM_SERIALIZATION defined, it does not + Choice ch = j.get(); +} +``` + +Example 2: Serialize enum macro + +The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses [`NLOHMANN_JSON_SERIALIZE_ENUM`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) to parse and serialize the enum. + +``` +#define JSON_DISABLE_ENUM_SERIALIZATION 1 +#include + +using json = nlohmann::json; + +enum class Choice +{ + first, + second, +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(Choice, +{ + { Choice::first, "first" }, + { Choice::second, "second" }, +}) + +int main() +{ + // uses user-defined to_json function defined by macro + const json j = Choice::first; + + // uses user-defined from_json function defined by macro + Choice ch = j.get(); +} +``` + +Example 3: User-defined serialization/deserialization functions + +The code below forces the library **not** to create default serialization/deserialization functions `from_json` and `to_json`, but uses user-defined functions to parse and serialize the enum. + +``` +#define JSON_DISABLE_ENUM_SERIALIZATION 1 +#include + +using json = nlohmann::json; + +enum class Choice +{ + first, + second, +}; + +void from_json(const json& j, Choice& ch) +{ + auto value = j.get(); + if (value == "first") + { + ch = Choice::first; + } + else if (value == "second") + { + ch = Choice::second; + } +} + +void to_json(json& j, const Choice& ch) +{ + if (ch == Choice::first) + { + j = "first"; + } + else if (ch == Choice::second) + { + j = "second"; + } +} + +int main() +{ + // uses user-defined to_json function + const json j = Choice::first; + + // uses user-defined from_json function + Choice ch = j.get(); +} +``` + +## See also + +- [JSON_DisableEnumSerialization](https://json.nlohmann.me/integration/cmake/#json_disableenumserialization) - CMake option to control the macro +- [`NLOHMANN_JSON_SERIALIZE_ENUM`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) - serialize/deserialize an enum + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_has_cpp_11.md b/api/macros/json_has_cpp_11.md new file mode 100644 index 000000000..6a30b55f0 --- /dev/null +++ b/api/macros/json_has_cpp_11.md @@ -0,0 +1,47 @@ +# JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26 + +```cpp +#define JSON_HAS_CPP_11 +#define JSON_HAS_CPP_14 +#define JSON_HAS_CPP_17 +#define JSON_HAS_CPP_20 +#define JSON_HAS_CPP_23 +#define JSON_HAS_CPP_26 +``` + +The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` +support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ +standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is +unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be +detected incorrectly. + +## Default definition + +The default value is detected based on preprocessor macros such as `#!cpp __cplusplus`, `#!cpp _HAS_CXX17`, or +`#!cpp _MSVC_LANG`. + +## Notes + +- When the C++ standard is detected automatically, `#!cpp JSON_HAS_CPP_11` is always defined. When you override the + detection by defining one of these macros manually, the automatic detection is skipped entirely, so you should define + all applicable macros (including `#!cpp JSON_HAS_CPP_11`) yourself. +- All macros are undefined outside the library. + +## Examples + +??? example + + The code below forces the library to use the C++14 standard: + + ```cpp + #define JSON_HAS_CPP_14 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.10.5. +- Added `JSON_HAS_CPP_23` in version 3.12.0. +- Added `JSON_HAS_CPP_26` in version 3.12.x. diff --git a/api/macros/json_has_cpp_11/index.html b/api/macros/json_has_cpp_11/index.html index 3dcadfd15..5812e8eef 100644 --- a/api/macros/json_has_cpp_11/index.html +++ b/api/macros/json_has_cpp_11/index.html @@ -8,4 +8,4 @@ #include <nlohmann/json.hpp> ... -

Version history

  • Added in version 3.10.5.
  • Added JSON_HAS_CPP_23 in version 3.12.0.
  • Added JSON_HAS_CPP_26 in version 3.12.x.
\ No newline at end of file +

Version history

  • Added in version 3.10.5.
  • Added JSON_HAS_CPP_23 in version 3.12.0.
  • Added JSON_HAS_CPP_26 in version 3.12.x.
\ No newline at end of file diff --git a/api/macros/json_has_cpp_11/index.md b/api/macros/json_has_cpp_11/index.md new file mode 100644 index 000000000..c13931d10 --- /dev/null +++ b/api/macros/json_has_cpp_11/index.md @@ -0,0 +1,40 @@ +# JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26 + +``` +#define JSON_HAS_CPP_11 +#define JSON_HAS_CPP_14 +#define JSON_HAS_CPP_17 +#define JSON_HAS_CPP_20 +#define JSON_HAS_CPP_23 +#define JSON_HAS_CPP_26 +``` + +The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly. + +## Default definition + +The default value is detected based on preprocessor macros such as `__cplusplus`, `_HAS_CXX17`, or `_MSVC_LANG`. + +## Notes + +- When the C++ standard is detected automatically, `JSON_HAS_CPP_11` is always defined. When you override the detection by defining one of these macros manually, the automatic detection is skipped entirely, so you should define all applicable macros (including `JSON_HAS_CPP_11`) yourself. +- All macros are undefined outside the library. + +## Examples + +Example + +The code below forces the library to use the C++14 standard: + +``` +#define JSON_HAS_CPP_14 1 +#include + +... +``` + +## Version history + +- Added in version 3.10.5. +- Added `JSON_HAS_CPP_23` in version 3.12.0. +- Added `JSON_HAS_CPP_26` in version 3.12.x. diff --git a/api/macros/json_has_filesystem.md b/api/macros/json_has_filesystem.md new file mode 100644 index 000000000..15c87b636 --- /dev/null +++ b/api/macros/json_has_filesystem.md @@ -0,0 +1,43 @@ +# JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM + +```cpp +#define JSON_HAS_FILESYSTEM /* value */ +#define JSON_HAS_EXPERIMENTAL_FILESYSTEM /* value */ +``` + +When compiling with C++17, the library provides conversions from and to +[`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path). As compiler support for filesystem is +limited, the library tries to detect whether +[``/`std::filesystem`](https://en.cppreference.com/w/cpp/header/filesystem) (`JSON_HAS_FILESYSTEM`) or +[``/`std::experimental::filesystem`](https://en.cppreference.com/w/cpp/header/experimental/filesystem) +(`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used. To override the built-in check, define `JSON_HAS_FILESYSTEM` or +`JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`. + +## Default definition + +The default value is detected based on the preprocessor macros `#!cpp __cpp_lib_filesystem`, +`#!cpp __cpp_lib_experimental_filesystem`, `#!cpp __has_include()`, or +`#!cpp __has_include()`. + +## Notes + +- Note that older compilers or older versions of libstdc++ also require the library `stdc++fs` to be linked to for + filesystem support. +- Both macros are undefined outside the library. + +## Examples + +??? example + + The code below forces the library to use the header ``. + + ```cpp + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.10.5. diff --git a/api/macros/json_has_filesystem/index.html b/api/macros/json_has_filesystem/index.html index 7776c51f5..9d178e496 100644 --- a/api/macros/json_has_filesystem/index.html +++ b/api/macros/json_has_filesystem/index.html @@ -4,4 +4,4 @@ #include <nlohmann/json.hpp> ... -

Version history

  • Added in version 3.10.5.
\ No newline at end of file +

Version history

  • Added in version 3.10.5.
\ No newline at end of file diff --git a/api/macros/json_has_filesystem/index.md b/api/macros/json_has_filesystem/index.md new file mode 100644 index 000000000..e6909473c --- /dev/null +++ b/api/macros/json_has_filesystem/index.md @@ -0,0 +1,34 @@ +# JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM + +``` +#define JSON_HAS_FILESYSTEM /* value */ +#define JSON_HAS_EXPERIMENTAL_FILESYSTEM /* value */ +``` + +When compiling with C++17, the library provides conversions from and to [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path). As compiler support for filesystem is limited, the library tries to detect whether [``/`std::filesystem`](https://en.cppreference.com/w/cpp/header/filesystem) (`JSON_HAS_FILESYSTEM`) or [``/`std::experimental::filesystem`](https://en.cppreference.com/w/cpp/header/experimental/filesystem) (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used. To override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`. + +## Default definition + +The default value is detected based on the preprocessor macros `__cpp_lib_filesystem`, `__cpp_lib_experimental_filesystem`, `__has_include()`, or `__has_include()`. + +## Notes + +- Note that older compilers or older versions of libstdc++ also require the library `stdc++fs` to be linked to for filesystem support. +- Both macros are undefined outside the library. + +## Examples + +Example + +The code below forces the library to use the header ``. + +``` +#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 +#include + +... +``` + +## Version history + +- Added in version 3.10.5. diff --git a/api/macros/json_has_ranges.md b/api/macros/json_has_ranges.md new file mode 100644 index 000000000..96d51052d --- /dev/null +++ b/api/macros/json_has_ranges.md @@ -0,0 +1,31 @@ +# JSON_HAS_RANGES + +```cpp +#define JSON_HAS_RANGES /* value */ +``` + +This macro indicates whether the standard library has any support for ranges. Implies support for concepts. +Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macro `#!cpp __cpp_lib_ranges`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +??? example + + The code below forces the library to enable support for ranges: + + ```cpp + #define JSON_HAS_RANGES 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_has_ranges/index.html b/api/macros/json_has_ranges/index.html index cad729351..ddd4bcb0c 100644 --- a/api/macros/json_has_ranges/index.html +++ b/api/macros/json_has_ranges/index.html @@ -3,4 +3,4 @@ #include <nlohmann/json.hpp> ... -

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/macros/json_has_ranges/index.md b/api/macros/json_has_ranges/index.md new file mode 100644 index 000000000..0386c7baa --- /dev/null +++ b/api/macros/json_has_ranges/index.md @@ -0,0 +1,30 @@ +# JSON_HAS_RANGES + +``` +#define JSON_HAS_RANGES /* value */ +``` + +This macro indicates whether the standard library has any support for ranges. Implies support for concepts. Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macro `__cpp_lib_ranges`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +Example + +The code below forces the library to enable support for ranges: + +``` +#define JSON_HAS_RANGES 1 +#include + +... +``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_has_static_rtti.md b/api/macros/json_has_static_rtti.md new file mode 100644 index 000000000..33d0703ab --- /dev/null +++ b/api/macros/json_has_static_rtti.md @@ -0,0 +1,31 @@ +# JSON_HAS_STATIC_RTTI + +```cpp +#define JSON_HAS_STATIC_RTTI /* value */ +``` + +This macro indicates whether the standard library has any support for RTTI (run time type information). +Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macro `#!cpp _HAS_STATIC_RTTI`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +??? example + + The code below forces the library to enable support for libraries with RTTI dependence: + + ```cpp + #define JSON_HAS_STATIC_RTTI 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.11.3. diff --git a/api/macros/json_has_static_rtti/index.html b/api/macros/json_has_static_rtti/index.html index c7f867248..1940cf449 100644 --- a/api/macros/json_has_static_rtti/index.html +++ b/api/macros/json_has_static_rtti/index.html @@ -3,4 +3,4 @@ #include <nlohmann/json.hpp> ... -

Version history

  • Added in version 3.11.3.
\ No newline at end of file +

Version history

  • Added in version 3.11.3.
\ No newline at end of file diff --git a/api/macros/json_has_static_rtti/index.md b/api/macros/json_has_static_rtti/index.md new file mode 100644 index 000000000..716bc676d --- /dev/null +++ b/api/macros/json_has_static_rtti/index.md @@ -0,0 +1,30 @@ +# JSON_HAS_STATIC_RTTI + +``` +#define JSON_HAS_STATIC_RTTI /* value */ +``` + +This macro indicates whether the standard library has any support for RTTI (run time type information). Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macro `_HAS_STATIC_RTTI`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +Example + +The code below forces the library to enable support for libraries with RTTI dependence: + +``` +#define JSON_HAS_STATIC_RTTI 1 +#include + +... +``` + +## Version history + +- Added in version 3.11.3. diff --git a/api/macros/json_has_std_format.md b/api/macros/json_has_std_format.md new file mode 100644 index 000000000..ad5b85fed --- /dev/null +++ b/api/macros/json_has_std_format.md @@ -0,0 +1,41 @@ +# JSON_HAS_STD_FORMAT + +```cpp +#define JSON_HAS_STD_FORMAT /* value */ +``` + +This macro indicates whether the standard library has support for `std::format`/`std::formatter` (that +is, the `` header). Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macros `#!cpp JSON_HAS_CPP_20` and +`#!cpp __cpp_lib_format`. + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! info "Enabled functionality" + + When this macro evaluates to `1`, the library provides a + [`std::formatter`](../basic_json/std_formatter.md) specialization so JSON values can be + used directly with `std::format`. + +## Examples + +??? example + + The code below forces the library to disable support for `std::format`, even if the standard library + would otherwise support it: + + ```cpp + #define JSON_HAS_STD_FORMAT 0 + #include + + ... + ``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/macros/json_has_std_format/index.html b/api/macros/json_has_std_format/index.html index bb7eaeaa4..120cf9c10 100644 --- a/api/macros/json_has_std_format/index.html +++ b/api/macros/json_has_std_format/index.html @@ -3,4 +3,4 @@ #include <nlohmann/json.hpp> ... -

Version history

  • Added in version 3.12.x.
\ No newline at end of file +

Version history

  • Added in version 3.12.x.
\ No newline at end of file diff --git a/api/macros/json_has_std_format/index.md b/api/macros/json_has_std_format/index.md new file mode 100644 index 000000000..067c6088c --- /dev/null +++ b/api/macros/json_has_std_format/index.md @@ -0,0 +1,36 @@ +# JSON_HAS_STD_FORMAT + +``` +#define JSON_HAS_STD_FORMAT /* value */ +``` + +This macro indicates whether the standard library has support for `std::format`/`std::formatter` (that is, the `` header). Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macros `JSON_HAS_CPP_20` and `__cpp_lib_format`. + +When the macro is not defined, the library will define it to its default value. + +## Notes + +Enabled functionality + +When this macro evaluates to `1`, the library provides a [`std::formatter`](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) specialization so JSON values can be used directly with `std::format`. + +## Examples + +Example + +The code below forces the library to disable support for `std::format`, even if the standard library would otherwise support it: + +``` +#define JSON_HAS_STD_FORMAT 0 +#include + +... +``` + +## Version history + +- Added in version 3.12.x. diff --git a/api/macros/json_has_three_way_comparison.md b/api/macros/json_has_three_way_comparison.md new file mode 100644 index 000000000..f52070ebf --- /dev/null +++ b/api/macros/json_has_three_way_comparison.md @@ -0,0 +1,32 @@ +# JSON_HAS_THREE_WAY_COMPARISON + +```cpp +#define JSON_HAS_THREE_WAY_COMPARISON /* value */ +``` + +This macro indicates whether the compiler and standard library support 3-way comparison. +Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macros `#!cpp __cpp_impl_three_way_comparison` +and `#!cpp __cpp_lib_three_way_comparison`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +??? example + + The code below forces the library to use 3-way comparison: + + ```cpp + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_has_three_way_comparison/index.html b/api/macros/json_has_three_way_comparison/index.html index d352c2753..df3c79d8f 100644 --- a/api/macros/json_has_three_way_comparison/index.html +++ b/api/macros/json_has_three_way_comparison/index.html @@ -3,4 +3,4 @@ #include <nlohmann/json.hpp> ... -

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/macros/json_has_three_way_comparison/index.md b/api/macros/json_has_three_way_comparison/index.md new file mode 100644 index 000000000..dab5d2262 --- /dev/null +++ b/api/macros/json_has_three_way_comparison/index.md @@ -0,0 +1,30 @@ +# JSON_HAS_THREE_WAY_COMPARISON + +``` +#define JSON_HAS_THREE_WAY_COMPARISON /* value */ +``` + +This macro indicates whether the compiler and standard library support 3-way comparison. Possible values are `1` when supported or `0` when unsupported. + +## Default definition + +The default value is detected based on the preprocessor macros `__cpp_impl_three_way_comparison` and `__cpp_lib_three_way_comparison`. + +When the macro is not defined, the library will define it to its default value. + +## Examples + +Example + +The code below forces the library to use 3-way comparison: + +``` +#define JSON_HAS_THREE_WAY_COMPARISON 1 +#include + +... +``` + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_no_io.md b/api/macros/json_no_io.md new file mode 100644 index 000000000..ef37384a5 --- /dev/null +++ b/api/macros/json_no_io.md @@ -0,0 +1,35 @@ +# JSON_NO_IO + +```cpp +#define JSON_NO_IO +``` + +When defined, headers ``, ``, ``, ``, and `` are not included and parse functions +relying on these headers are excluded. This is relevant for environments where these I/O functions are disallowed for +security reasons (e.g., Intel Software Guard Extensions (SGX)). + +## Default definition + +By default, `#!cpp JSON_NO_IO` is not defined. + +```cpp +#undef JSON_NO_IO +``` + +## Examples + +??? example + + The code below forces the library not to use the headers ``, ``, ``, ``, and + ``. + + ```cpp + #define JSON_NO_IO 1 + #include + + ... + ``` + +## Version history + +- Added in version 3.10.0. diff --git a/api/macros/json_no_io/index.html b/api/macros/json_no_io/index.html index 3f2fb297f..8acedfe78 100644 --- a/api/macros/json_no_io/index.html +++ b/api/macros/json_no_io/index.html @@ -4,4 +4,4 @@ #include <nlohmann/json.hpp> ... -

Version history

  • Added in version 3.10.0.
\ No newline at end of file +

Version history

  • Added in version 3.10.0.
\ No newline at end of file diff --git a/api/macros/json_no_io/index.md b/api/macros/json_no_io/index.md new file mode 100644 index 000000000..fe927a632 --- /dev/null +++ b/api/macros/json_no_io/index.md @@ -0,0 +1,32 @@ +# JSON_NO_IO + +``` +#define JSON_NO_IO +``` + +When defined, headers ``, ``, ``, ``, and `` are not included and parse functions relying on these headers are excluded. This is relevant for environments where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)). + +## Default definition + +By default, `JSON_NO_IO` is not defined. + +``` +#undef JSON_NO_IO +``` + +## Examples + +Example + +The code below forces the library not to use the headers ``, ``, ``, ``, and ``. + +``` +#define JSON_NO_IO 1 +#include + +... +``` + +## Version history + +- Added in version 3.10.0. diff --git a/api/macros/json_noexception.md b/api/macros/json_noexception.md new file mode 100644 index 000000000..c801b8567 --- /dev/null +++ b/api/macros/json_noexception.md @@ -0,0 +1,45 @@ +# JSON_NOEXCEPTION + +```cpp +#define JSON_NOEXCEPTION +``` + +Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. When defining `JSON_NOEXCEPTION`, `#!cpp try` +is replaced by `#!cpp if (true)`, `#!cpp catch` is replaced by `#!cpp if (false)`, and `#!cpp throw` is replaced by +`#!cpp std::abort()`. + +The same effect is achieved by setting the compiler flag `-fno-exceptions`. + +## Default definition + +By default, the macro is not defined. + +```cpp +#undef JSON_NOEXCEPTION +``` + +## Notes + +The explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not +available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824). + +## Examples + +??? example + + The code below switches off exceptions in the library. + + ```cpp + #define JSON_NOEXCEPTION 1 + #include + + ... + ``` + +## See also + +- [Switch off exceptions](../../home/exceptions.md#switch-off-exceptions) for more information how to switch off exceptions + +## Version history + +Added in version 2.1.0. diff --git a/api/macros/json_noexception/index.html b/api/macros/json_noexception/index.html index 40eccf717..38ca37859 100644 --- a/api/macros/json_noexception/index.html +++ b/api/macros/json_noexception/index.html @@ -4,4 +4,4 @@ #include <nlohmann/json.hpp> ... -

See also

Version history

Added in version 2.1.0.

\ No newline at end of file +

See also

Version history

Added in version 2.1.0.

\ No newline at end of file diff --git a/api/macros/json_noexception/index.md b/api/macros/json_noexception/index.md new file mode 100644 index 000000000..9d4cee0aa --- /dev/null +++ b/api/macros/json_noexception/index.md @@ -0,0 +1,42 @@ +# JSON_NOEXCEPTION + +``` +#define JSON_NOEXCEPTION +``` + +Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. When defining `JSON_NOEXCEPTION`, `try` is replaced by `if (true)`, `catch` is replaced by `if (false)`, and `throw` is replaced by `std::abort()`. + +The same effect is achieved by setting the compiler flag `-fno-exceptions`. + +## Default definition + +By default, the macro is not defined. + +``` +#undef JSON_NOEXCEPTION +``` + +## Notes + +The explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824). + +## Examples + +Example + +The code below switches off exceptions in the library. + +``` +#define JSON_NOEXCEPTION 1 +#include + +... +``` + +## See also + +- [Switch off exceptions](https://json.nlohmann.me/home/exceptions/#switch-off-exceptions) for more information how to switch off exceptions + +## Version history + +Added in version 2.1.0. diff --git a/api/macros/json_skip_library_version_check.md b/api/macros/json_skip_library_version_check.md new file mode 100644 index 000000000..37e91b3c6 --- /dev/null +++ b/api/macros/json_skip_library_version_check.md @@ -0,0 +1,48 @@ +# JSON_SKIP_LIBRARY_VERSION_CHECK + +```cpp +#define JSON_SKIP_LIBRARY_VERSION_CHECK +``` + +When defined, the library will not create a compiler warning when a different version of the library was already +included. + +## Default definition + +By default, the macro is not defined. + +```cpp +#undef JSON_SKIP_LIBRARY_VERSION_CHECK +``` + +## Notes + +!!! danger "ABI compatibility" + + Mixing different library versions in the same code can be a problem as the different versions may not be ABI + compatible. + +## Examples + +??? example + + The code below switches off the warning about including a different version of the library. + + ```cpp + #define JSON_SKIP_LIBRARY_VERSION_CHECK 1 + #include + + ... + ``` + +!!! example + + The following warning will be shown in case a different version of the library was already included: + + ``` + Already included a different version of the library! + ``` + +## Version history + +Added in version 3.11.0. diff --git a/api/macros/json_skip_library_version_check/index.html b/api/macros/json_skip_library_version_check/index.html index 06ba86cb3..06c25e323 100644 --- a/api/macros/json_skip_library_version_check/index.html +++ b/api/macros/json_skip_library_version_check/index.html @@ -5,4 +5,4 @@ ...

Example

The following warning will be shown in case a different version of the library was already included:

Already included a different version of the library!
-

Version history

Added in version 3.11.0.

\ No newline at end of file +

Version history

Added in version 3.11.0.

\ No newline at end of file diff --git a/api/macros/json_skip_library_version_check/index.md b/api/macros/json_skip_library_version_check/index.md new file mode 100644 index 000000000..9fdb55909 --- /dev/null +++ b/api/macros/json_skip_library_version_check/index.md @@ -0,0 +1,46 @@ +# JSON_SKIP_LIBRARY_VERSION_CHECK + +``` +#define JSON_SKIP_LIBRARY_VERSION_CHECK +``` + +When defined, the library will not create a compiler warning when a different version of the library was already included. + +## Default definition + +By default, the macro is not defined. + +``` +#undef JSON_SKIP_LIBRARY_VERSION_CHECK +``` + +## Notes + +ABI compatibility + +Mixing different library versions in the same code can be a problem as the different versions may not be ABI compatible. + +## Examples + +Example + +The code below switches off the warning about including a different version of the library. + +``` +#define JSON_SKIP_LIBRARY_VERSION_CHECK 1 +#include + +... +``` + +Example + +The following warning will be shown in case a different version of the library was already included: + +``` +Already included a different version of the library! +``` + +## Version history + +Added in version 3.11.0. diff --git a/api/macros/json_skip_unsupported_compiler_check.md b/api/macros/json_skip_unsupported_compiler_check.md new file mode 100644 index 000000000..52cdbd172 --- /dev/null +++ b/api/macros/json_skip_unsupported_compiler_check.md @@ -0,0 +1,33 @@ +# JSON_SKIP_UNSUPPORTED_COMPILER_CHECK + +```cpp +#define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK +``` + +When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows +using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used. + +## Default definition + +By default, the macro is not defined. + +```cpp +#undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK +``` + +## Examples + +??? example + + The code below switches off the check whether the compiler is supported. + + ```cpp + #define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1 + #include + + ... + ``` + +## Version history + +Added in version 3.2.0. diff --git a/api/macros/json_skip_unsupported_compiler_check/index.html b/api/macros/json_skip_unsupported_compiler_check/index.html index 96720cbbe..de57b7117 100644 --- a/api/macros/json_skip_unsupported_compiler_check/index.html +++ b/api/macros/json_skip_unsupported_compiler_check/index.html @@ -4,4 +4,4 @@ #include <nlohmann/json.hpp> ... -

Version history

Added in version 3.2.0.

\ No newline at end of file +

Version history

Added in version 3.2.0.

\ No newline at end of file diff --git a/api/macros/json_skip_unsupported_compiler_check/index.md b/api/macros/json_skip_unsupported_compiler_check/index.md new file mode 100644 index 000000000..b3c7c4a2f --- /dev/null +++ b/api/macros/json_skip_unsupported_compiler_check/index.md @@ -0,0 +1,32 @@ +# JSON_SKIP_UNSUPPORTED_COMPILER_CHECK + +``` +#define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK +``` + +When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used. + +## Default definition + +By default, the macro is not defined. + +``` +#undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK +``` + +## Examples + +Example + +The code below switches off the check whether the compiler is supported. + +``` +#define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1 +#include + +... +``` + +## Version history + +Added in version 3.2.0. diff --git a/api/macros/json_throw_user.md b/api/macros/json_throw_user.md new file mode 100644 index 000000000..b02918cf8 --- /dev/null +++ b/api/macros/json_throw_user.md @@ -0,0 +1,75 @@ +# JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER + +```cpp +// (1) +#define JSON_CATCH_USER(exception) /* value */ +// (2) +#define JSON_THROW_USER(exception) /* value */ +// (3) +#define JSON_TRY_USER /* value */ +``` + +Controls how exceptions are handled by the library. + +1. This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library. + The argument is the type of the exception to catch. As of version 3.8.0, the library only catches `std::out_of_range` + exceptions internally to rethrow them as [`json::out_of_range`](../../home/exceptions.md#out-of-range) exceptions. + The macro is always followed by a scope. +2. This macro overrides `#!cpp throw` calls inside the library. The argument is the exception to be thrown. Note that + `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield + undefined behavior. +3. This macro overrides `#!cpp try` calls inside the library. It has no arguments and is always followed by a scope. + +## Parameters + +`exception` (in) +: an exception type + +## Default definition + +By default, the macros map to their respective C++ keywords: + +```cpp +#define JSON_CATCH_USER(exception) catch(exception) +#define JSON_THROW_USER(exception) throw exception +#define JSON_TRY_USER try +``` + +When exceptions are switched off, the `#!cpp try` block is executed unconditionally, and throwing exceptions is +replaced by calling [`std::abort`](https://en.cppreference.com/w/cpp/utility/program/abort) to make reaching the +`#!cpp throw` branch abort the process. + +```cpp +#define JSON_THROW_USER(exception) std::abort() +#define JSON_TRY_USER if (true) +#define JSON_CATCH_USER(exception) if (false) +``` + +## Examples + +??? example + + The code below switches off exceptions and creates a log entry with a detailed error message in case of errors. + + ```cpp + #include + + #define JSON_TRY_USER if(true) + #define JSON_CATCH_USER(exception) if(false) + #define JSON_THROW_USER(exception) \ + {std::clog << "Error in " << __FILE__ << ":" << __LINE__ \ + << " (function " << __FUNCTION__ << ") - " \ + << (exception).what() << std::endl; \ + std::abort();} + + #include + ``` + +## See also + +- [Switch off exceptions](../../home/exceptions.md#switch-off-exceptions) for more information how to switch off exceptions +- [JSON_NOEXCEPTION](json_noexception.md) - switch off exceptions + +## Version history + +- Added in version 3.1.0. diff --git a/api/macros/json_throw_user/index.html b/api/macros/json_throw_user/index.html index fd3a3498c..929592858 100644 --- a/api/macros/json_throw_user/index.html +++ b/api/macros/json_throw_user/index.html @@ -21,4 +21,4 @@ std::abort();} #include <nlohmann/json.hpp> -

See also

Version history

  • Added in version 3.1.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.1.0.
\ No newline at end of file diff --git a/api/macros/json_throw_user/index.md b/api/macros/json_throw_user/index.md new file mode 100644 index 000000000..383185628 --- /dev/null +++ b/api/macros/json_throw_user/index.md @@ -0,0 +1,67 @@ +# JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER + +``` +// (1) +#define JSON_CATCH_USER(exception) /* value */ +// (2) +#define JSON_THROW_USER(exception) /* value */ +// (3) +#define JSON_TRY_USER /* value */ +``` + +Controls how exceptions are handled by the library. + +1. This macro overrides [`catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library. The argument is the type of the exception to catch. As of version 3.8.0, the library only catches `std::out_of_range` exceptions internally to rethrow them as [`json::out_of_range`](https://json.nlohmann.me/home/exceptions/#out-of-range) exceptions. The macro is always followed by a scope. +1. This macro overrides `throw` calls inside the library. The argument is the exception to be thrown. Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior. +1. This macro overrides `try` calls inside the library. It has no arguments and is always followed by a scope. + +## Parameters + +`exception` (in) : an exception type + +## Default definition + +By default, the macros map to their respective C++ keywords: + +``` +#define JSON_CATCH_USER(exception) catch(exception) +#define JSON_THROW_USER(exception) throw exception +#define JSON_TRY_USER try +``` + +When exceptions are switched off, the `try` block is executed unconditionally, and throwing exceptions is replaced by calling [`std::abort`](https://en.cppreference.com/w/cpp/utility/program/abort) to make reaching the `throw` branch abort the process. + +``` +#define JSON_THROW_USER(exception) std::abort() +#define JSON_TRY_USER if (true) +#define JSON_CATCH_USER(exception) if (false) +``` + +## Examples + +Example + +The code below switches off exceptions and creates a log entry with a detailed error message in case of errors. + +``` +#include + +#define JSON_TRY_USER if(true) +#define JSON_CATCH_USER(exception) if(false) +#define JSON_THROW_USER(exception) \ + {std::clog << "Error in " << __FILE__ << ":" << __LINE__ \ + << " (function " << __FUNCTION__ << ") - " \ + << (exception).what() << std::endl; \ + std::abort();} + +#include +``` + +## See also + +- [Switch off exceptions](https://json.nlohmann.me/home/exceptions/#switch-off-exceptions) for more information how to switch off exceptions +- [JSON_NOEXCEPTION](https://json.nlohmann.me/api/macros/json_noexception/index.md) - switch off exceptions + +## Version history + +- Added in version 3.1.0. diff --git a/api/macros/json_use_global_udls.md b/api/macros/json_use_global_udls.md new file mode 100644 index 000000000..3110d4662 --- /dev/null +++ b/api/macros/json_use_global_udls.md @@ -0,0 +1,99 @@ +# JSON_USE_GLOBAL_UDLS + +```cpp +#define JSON_USE_GLOBAL_UDLS /* value */ +``` + +When defined to `1`, the user-defined string literals (UDLs) are placed into the global namespace instead of +`nlohmann::literals::json_literals`. + +## Default definition + +The default value is `1`. + +```cpp +#define JSON_USE_GLOBAL_UDLS 1 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! info "Future behavior change" + + The user-defined string literals will be removed from the global namespace in the next major release of the library. + + To prepare existing code, define `JSON_USE_GLOBAL_UDLS` to `0` and bring the string literals into scope where + needed. Refer to any of the [string literals](#see-also) for details. + +!!! hint "CMake option" + + The placement of user-defined string literals can also be controlled with the CMake option + [`JSON_GlobalUDLs`](../../integration/cmake.md#json_globaludls) (`ON` by default) which defines + `JSON_USE_GLOBAL_UDLS` accordingly. + +## Examples + +??? example "Example 1: Default behavior" + + The code below shows the default behavior using the `_json` UDL. + + ```cpp + #include + + #include + + int main() + { + auto j = "42"_json; + + std::cout << j << std::endl; + } + ``` + + Output: + + ```json + 42 + ``` + +??? example "Example 2: Namespaced UDLs" + + The code below shows how UDLs need to be brought into scope before using `_json` when `JSON_USE_GLOBAL_UDLS` is + defined to `0`. + + ```cpp + #define JSON_USE_GLOBAL_UDLS 0 + #include + + #include + + int main() + { + // auto j = "42"_json; // This line would fail to compile, + // because the UDLs are not in the global namespace + + // Bring the UDLs into scope + using namespace nlohmann::json_literals; + + auto j = "42"_json; + + std::cout << j << std::endl; + } + ``` + + Output: + + ```json + 42 + ``` + +## See also + +- [`operator""_json`](../operator_literal_json.md) +- [`operator""_json_pointer`](../operator_literal_json_pointer.md) +- [:simple-cmake: JSON_GlobalUDLs](../../integration/cmake.md#json_globaludls) - CMake option to control the macro + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_use_global_udls/index.html b/api/macros/json_use_global_udls/index.html index 47cf910e1..cca48f796 100644 --- a/api/macros/json_use_global_udls/index.html +++ b/api/macros/json_use_global_udls/index.html @@ -29,4 +29,4 @@ std::cout << j << std::endl; }

Output:

42
-

See also

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/macros/json_use_global_udls/index.md b/api/macros/json_use_global_udls/index.md new file mode 100644 index 000000000..81458f4c0 --- /dev/null +++ b/api/macros/json_use_global_udls/index.md @@ -0,0 +1,94 @@ +# JSON_USE_GLOBAL_UDLS + +``` +#define JSON_USE_GLOBAL_UDLS /* value */ +``` + +When defined to `1`, the user-defined string literals (UDLs) are placed into the global namespace instead of `nlohmann::literals::json_literals`. + +## Default definition + +The default value is `1`. + +``` +#define JSON_USE_GLOBAL_UDLS 1 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +Future behavior change + +The user-defined string literals will be removed from the global namespace in the next major release of the library. + +To prepare existing code, define `JSON_USE_GLOBAL_UDLS` to `0` and bring the string literals into scope where needed. Refer to any of the [string literals](#see-also) for details. + +CMake option + +The placement of user-defined string literals can also be controlled with the CMake option [`JSON_GlobalUDLs`](https://json.nlohmann.me/integration/cmake/#json_globaludls) (`ON` by default) which defines `JSON_USE_GLOBAL_UDLS` accordingly. + +## Examples + +Example 1: Default behavior + +The code below shows the default behavior using the `_json` UDL. + +``` +#include + +#include + +int main() +{ + auto j = "42"_json; + + std::cout << j << std::endl; +} +``` + +Output: + +``` +42 +``` + +Example 2: Namespaced UDLs + +The code below shows how UDLs need to be brought into scope before using `_json` when `JSON_USE_GLOBAL_UDLS` is defined to `0`. + +``` +#define JSON_USE_GLOBAL_UDLS 0 +#include + +#include + +int main() +{ + // auto j = "42"_json; // This line would fail to compile, + // because the UDLs are not in the global namespace + + // Bring the UDLs into scope + using namespace nlohmann::json_literals; + + auto j = "42"_json; + + std::cout << j << std::endl; +} +``` + +Output: + +``` +42 +``` + +## See also + +- [`operator""_json`](https://json.nlohmann.me/api/operator_literal_json/index.md) +- [`operator""_json_pointer`](https://json.nlohmann.me/api/operator_literal_json_pointer/index.md) +- [JSON_GlobalUDLs](https://json.nlohmann.me/integration/cmake/#json_globaludls) - CMake option to control the macro + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_use_implicit_conversions.md b/api/macros/json_use_implicit_conversions.md new file mode 100644 index 000000000..22f6d0072 --- /dev/null +++ b/api/macros/json_use_implicit_conversions.md @@ -0,0 +1,60 @@ +# JSON_USE_IMPLICIT_CONVERSIONS + +```cpp +#define JSON_USE_IMPLICIT_CONVERSIONS /* value */ +``` + +When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. The +value directly affects [`operator ValueType`](../basic_json/operator_ValueType.md). + +## Default definition + +By default, implicit conversions are enabled. + +```cpp +#define JSON_USE_IMPLICIT_CONVERSIONS 1 +``` + +## Notes + +!!! info "Future behavior change" + + Implicit conversions will be switched off by default in the next major release of the library. + + You can prepare existing code by already defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` and replace any implicit + conversions with calls to [`get`](../basic_json/get.md). + +!!! hint "CMake option" + + Implicit conversions can also be controlled with the CMake option + [`JSON_ImplicitConversions`](../../integration/cmake.md#json_implicitconversions) + (`ON` by default) which defines `JSON_USE_IMPLICIT_CONVERSIONS` accordingly. + +## Examples + +??? example + + This is an example for an implicit conversion: + + ```cpp + json j = "Hello, world!"; + std::string s = j; + ``` + + When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be + written like this: + + ```cpp + json j = "Hello, world!"; + auto s = j.get(); + ``` + +## See also + +- [**operator ValueType**](../basic_json/operator_ValueType.md) - get a value (implicit) +- [**get**](../basic_json/get.md) - get a value (explicit) +- [:simple-cmake: JSON_ImplicitConversions](../../integration/cmake.md#json_implicitconversions) - CMake option to control the macro + +## Version history + +- Added in version 3.9.0. diff --git a/api/macros/json_use_implicit_conversions/index.html b/api/macros/json_use_implicit_conversions/index.html index 19b5448db..258f70a19 100644 --- a/api/macros/json_use_implicit_conversions/index.html +++ b/api/macros/json_use_implicit_conversions/index.html @@ -4,4 +4,4 @@ std::string s = j;

When JSON_USE_IMPLICIT_CONVERSIONS is defined to 0, the code above does no longer compile. Instead, it must be written like this:

json j = "Hello, world!";
 auto s = j.get<std::string>();
-

See also

Version history

  • Added in version 3.9.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.9.0.
\ No newline at end of file diff --git a/api/macros/json_use_implicit_conversions/index.md b/api/macros/json_use_implicit_conversions/index.md new file mode 100644 index 000000000..1054a6204 --- /dev/null +++ b/api/macros/json_use_implicit_conversions/index.md @@ -0,0 +1,55 @@ +# JSON_USE_IMPLICIT_CONVERSIONS + +``` +#define JSON_USE_IMPLICIT_CONVERSIONS /* value */ +``` + +When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. The value directly affects [`operator ValueType`](https://json.nlohmann.me/api/basic_json/operator_ValueType/index.md). + +## Default definition + +By default, implicit conversions are enabled. + +``` +#define JSON_USE_IMPLICIT_CONVERSIONS 1 +``` + +## Notes + +Future behavior change + +Implicit conversions will be switched off by default in the next major release of the library. + +You can prepare existing code by already defining `JSON_USE_IMPLICIT_CONVERSIONS` to `0` and replace any implicit conversions with calls to [`get`](https://json.nlohmann.me/api/basic_json/get/index.md). + +CMake option + +Implicit conversions can also be controlled with the CMake option [`JSON_ImplicitConversions`](https://json.nlohmann.me/integration/cmake/#json_implicitconversions) (`ON` by default) which defines `JSON_USE_IMPLICIT_CONVERSIONS` accordingly. + +## Examples + +Example + +This is an example for an implicit conversion: + +``` +json j = "Hello, world!"; +std::string s = j; +``` + +When `JSON_USE_IMPLICIT_CONVERSIONS` is defined to `0`, the code above does no longer compile. Instead, it must be written like this: + +``` +json j = "Hello, world!"; +auto s = j.get(); +``` + +## See also + +- [**operator ValueType**](https://json.nlohmann.me/api/basic_json/operator_ValueType/index.md) - get a value (implicit) +- [**get**](https://json.nlohmann.me/api/basic_json/get/index.md) - get a value (explicit) +- [JSON_ImplicitConversions](https://json.nlohmann.me/integration/cmake/#json_implicitconversions) - CMake option to control the macro + +## Version history + +- Added in version 3.9.0. diff --git a/api/macros/json_use_legacy_discarded_value_comparison.md b/api/macros/json_use_legacy_discarded_value_comparison.md new file mode 100644 index 000000000..f026a9825 --- /dev/null +++ b/api/macros/json_use_legacy_discarded_value_comparison.md @@ -0,0 +1,81 @@ +# JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + +```cpp +#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON /* value */ +``` + +This macro enables the (incorrect) legacy comparison behavior of discarded JSON values. Possible values are `1` to +enable or `0` to disable (default). + +When enabled, comparisons involving at least one discarded JSON value yield results as follows: + +| **Operator** | **Result** | +|--------------|---------------| +| `==` | `#!cpp false` | +| `!=` | `#!cpp true` | +| `<` | `#!cpp false` | +| `<=` | `#!cpp true` | +| `>=` | `#!cpp true` | +| `>` | `#!cpp false` | + +Otherwise, comparisons involving at least one discarded JSON value always yield `#!cpp false`. + +## Default definition + +The default value is `0`. + +```cpp +#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +!!! warning "Inconsistent behavior in C++20 and beyond" + + When targeting C++20 or above, enabling the legacy comparison behavior is _strongly_ + discouraged. + + - The 3-way comparison operator (`<=>`) will always give the correct result + (`#!cpp std::partial_ordering::unordered`) regardless of the value of + `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`. + - Overloads for the equality and relational operators emulate the legacy behavior. + + Code outside your control may use either 3-way comparison or the equality and relational operators, resulting in + inconsistent and unpredictable behavior. + + See [`operator<=>`](../basic_json/operator_spaceship.md) for more information on 3-way comparison. + +!!! warning "Deprecation" + + The legacy comparison behavior is deprecated and may be removed in a future major version release. + + New code should not depend on it and existing code should try to remove or rewrite expressions relying on it. + +!!! hint "CMake option" + + Legacy comparison can also be controlled with the CMake option + [`JSON_LegacyDiscardedValueComparison`](../../integration/cmake.md#json_legacydiscardedvaluecomparison) + (`OFF` by default) which defines `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON` accordingly. + +## Examples + +??? example + + The code below switches on the legacy discarded value comparison behavior in the library. + + ```cpp + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 + #include + + ... + ``` + +## See also + +- [:simple-cmake: JSON_LegacyDiscardedValueComparison](../../integration/cmake.md#json_legacydiscardedvaluecomparison) - CMake option to control the macro + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/json_use_legacy_discarded_value_comparison/index.html b/api/macros/json_use_legacy_discarded_value_comparison/index.html index bfd839f55..33f2d3b02 100644 --- a/api/macros/json_use_legacy_discarded_value_comparison/index.html +++ b/api/macros/json_use_legacy_discarded_value_comparison/index.html @@ -4,4 +4,4 @@ #include <nlohmann/json.hpp> ... -

See also

Version history

  • Added in version 3.11.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.0.
\ No newline at end of file diff --git a/api/macros/json_use_legacy_discarded_value_comparison/index.md b/api/macros/json_use_legacy_discarded_value_comparison/index.md new file mode 100644 index 000000000..84e509a8c --- /dev/null +++ b/api/macros/json_use_legacy_discarded_value_comparison/index.md @@ -0,0 +1,74 @@ +# JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + +``` +#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON /* value */ +``` + +This macro enables the (incorrect) legacy comparison behavior of discarded JSON values. Possible values are `1` to enable or `0` to disable (default). + +When enabled, comparisons involving at least one discarded JSON value yield results as follows: + +| **Operator** | **Result** | +| ------------ | ---------- | +| `==` | `false` | +| `!=` | `true` | +| `<` | `false` | +| `<=` | `true` | +| `>=` | `true` | +| `>` | `false` | + +Otherwise, comparisons involving at least one discarded JSON value always yield `false`. + +## Default definition + +The default value is `0`. + +``` +#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Notes + +Inconsistent behavior in C++20 and beyond + +When targeting C++20 or above, enabling the legacy comparison behavior is *strongly* discouraged. + +- The 3-way comparison operator (`<=>`) will always give the correct result (`std::partial_ordering::unordered`) regardless of the value of `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`. +- Overloads for the equality and relational operators emulate the legacy behavior. + +Code outside your control may use either 3-way comparison or the equality and relational operators, resulting in inconsistent and unpredictable behavior. + +See [`operator<=>`](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) for more information on 3-way comparison. + +Deprecation + +The legacy comparison behavior is deprecated and may be removed in a future major version release. + +New code should not depend on it and existing code should try to remove or rewrite expressions relying on it. + +CMake option + +Legacy comparison can also be controlled with the CMake option [`JSON_LegacyDiscardedValueComparison`](https://json.nlohmann.me/integration/cmake/#json_legacydiscardedvaluecomparison) (`OFF` by default) which defines `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON` accordingly. + +## Examples + +Example + +The code below switches on the legacy discarded value comparison behavior in the library. + +``` +#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 +#include + +... +``` + +## See also + +- [JSON_LegacyDiscardedValueComparison](https://json.nlohmann.me/integration/cmake/#json_legacydiscardedvaluecomparison) - CMake option to control the macro + +## Version history + +- Added in version 3.11.0. diff --git a/api/macros/nlohmann_define_derived_type.md b/api/macros/nlohmann_define_derived_type.md new file mode 100644 index 000000000..433d5b9a0 --- /dev/null +++ b/api/macros/nlohmann_define_derived_type.md @@ -0,0 +1,177 @@ +

NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE

+ +```cpp +// (1) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(type, base_type, member...) +// (2) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) +// (3) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...) + +// (4) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(type, base_type, member...) +// (5) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) +// (6) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...) +``` + +These macros can be used to simplify the serialization/deserialization of derived types if you want to use a JSON +object as serialization and want to use the member variable names as object keys in that object. + +- Macros 1, 2, and 3 are to be defined **inside** the class/struct to create code for. +Like [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](nlohmann_define_type_intrusive.md), they can access private members. +- Macros 4, 5, and 6 are to be defined **outside** the class/struct to create code for, but **inside** its namespace. +Like [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](nlohmann_define_type_non_intrusive.md), +they **cannot** access private members. + +The first parameter is the name of the derived class/struct, +the second parameter is the name of the base class/struct and all remaining parameters name the members. +The base type **must** be already serializable/deserializable. + +- Macros 1 and 4 will use [`at`](../basic_json/at.md) during deserialization and will throw + [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a key is missing in the JSON object. +- Macros 2 and 5 will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the + respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function + default constructs an object and uses its values as the defaults when calling the `value` function. + +Summary: + +| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | +|------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|---------------------------------------------------------------| +|
:octicons-check-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
| **NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE** | +|
:octicons-check-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-check-circle-fill-24:
| **NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT** | +|
:octicons-check-circle-fill-24:
|
:octicons-check-circle-fill-24:
|
:octicons-skip-fill-24:
| **NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE** | +|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
| **NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE** | +|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-check-circle-fill-24:
| **NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT** | +|
:octicons-x-circle-fill-24:
|
:octicons-check-circle-fill-24:
|
:octicons-skip-fill-24:
| **NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE** | + +## Parameters + +`type` (in) +: name of the type (class, struct) to serialize/deserialize + +`base_type` (in) +: name of the base type (class, struct) `type` is derived from + +`member` (in) +: name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list + +## Default definition + +Macros 1 and 2 add two friend functions to the class which take care of the serialization and deserialization: + +```cpp +template +friend void to_json(BasicJsonType&, const type&); +template +friend void from_json(const BasicJsonType&, type&); +``` + +Macros 4 and 5 add two functions to the namespace which take care of the serialization and deserialization: + +```cpp +template +void to_json(BasicJsonType&, const type&); +template +void from_json(const BasicJsonType&, type&); +``` + +Macros 3 and 6 add one function to the namespace, which takes care of the serialization only: + +```cpp +template +void to_json(BasicJsonType&, const type&); +``` + +In first two cases, they call the `to_json`/`from_json` functions of the base type +before serializing/deserializing the members of the derived type: + +```cpp +class A { /* ... */ }; +class B : public A { /* ... */ }; + +template +void to_json(BasicJsonType& j, const B& b) { + nlohmann::to_json(j, static_cast(b)); + // ... +} + +template +void from_json(const BasicJsonType& j, B& b) { + nlohmann::from_json(j, static_cast(b)); + // ... +} +``` + +In the third case, only `to_json` will be called: + +```cpp +class A { /* ... */ }; +class B : public A { /* ... */ }; + +template +void to_json(BasicJsonType& j, const B& b) { + nlohmann::to_json(j, static_cast(b)); + // ... +} +``` + +## Notes + +!!! info "Prerequisites" + + - Macros 1, 2, and 3 have the same prerequisites of [NLOHMANN_DEFINE_TYPE_INTRUSIVE](nlohmann_define_type_intrusive.md). + - Macros 4, 5, and 6 have the same prerequisites of [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE](nlohmann_define_type_non_intrusive.md). + - Serialization/deserialization of base types must be defined. + +!!! warning "Implementation limits" + + See Implementation limits for [NLOHMANN_DEFINE_TYPE_INTRUSIVE](nlohmann_define_type_intrusive.md) and + [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE](nlohmann_define_type_non_intrusive.md), respectively. + +## Examples + +??? example "NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE" + + Consider the following complete example: + + ```cpp hl_lines="28" + --8<-- "examples/nlohmann_define_derived_type_intrusive_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_derived_type_intrusive_macro.output" + ``` + + Notes: + + - `A` and `B` are default-constructible. This is a requirement for using the macro. + - `A` has private members and is not a derived class. Hence, macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is used. + - As `B` is a derived class, `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is not applicable, but + `NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE` must be used. + - The macro `NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE` is used _inside_ the class use as + `NLOHMANN_DEFINE_TYPE_INTRUSIVE`. + +## See also + +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / + NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE](nlohmann_define_type_intrusive.md) + for similar macros that can be defined _inside_ a non-derived type. +- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](nlohmann_define_type_non_intrusive.md) + for similar macros that can be defined _outside_ a non-derived type. +- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. + +## Version history + +1. Added in version 3.12.0. +2. Added in version 3.12.0. +3. Added in version 3.12.0. +4. Added in version 3.12.0. +5. Added in version 3.12.0. +6. Added in version 3.12.0. diff --git a/api/macros/nlohmann_define_derived_type/index.html b/api/macros/nlohmann_define_derived_type/index.html index fc79a383d..18a0b7778 100644 --- a/api/macros/nlohmann_define_derived_type/index.html +++ b/api/macros/nlohmann_define_derived_type/index.html @@ -86,4 +86,4 @@ "Ba": 23, "Bb": 42 } -

Notes:

  • A and B are default-constructible. This is a requirement for using the macro.
  • A has private members and is not a derived class. Hence, macro NLOHMANN_DEFINE_TYPE_INTRUSIVE is used.
  • As B is a derived class, NLOHMANN_DEFINE_TYPE_INTRUSIVE is not applicable, but NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE must be used.
  • The macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE is used inside the class use as NLOHMANN_DEFINE_TYPE_INTRUSIVE.

See also

Version history

  1. Added in version 3.12.0.
  2. Added in version 3.12.0.
  3. Added in version 3.12.0.
  4. Added in version 3.12.0.
  5. Added in version 3.12.0.
  6. Added in version 3.12.0.
\ No newline at end of file +

Notes:

  • A and B are default-constructible. This is a requirement for using the macro.
  • A has private members and is not a derived class. Hence, macro NLOHMANN_DEFINE_TYPE_INTRUSIVE is used.
  • As B is a derived class, NLOHMANN_DEFINE_TYPE_INTRUSIVE is not applicable, but NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE must be used.
  • The macro NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE is used inside the class use as NLOHMANN_DEFINE_TYPE_INTRUSIVE.

See also

Version history

  1. Added in version 3.12.0.
  2. Added in version 3.12.0.
  3. Added in version 3.12.0.
  4. Added in version 3.12.0.
  5. Added in version 3.12.0.
  6. Added in version 3.12.0.
\ No newline at end of file diff --git a/api/macros/nlohmann_define_derived_type/index.md b/api/macros/nlohmann_define_derived_type/index.md new file mode 100644 index 000000000..34513e277 --- /dev/null +++ b/api/macros/nlohmann_define_derived_type/index.md @@ -0,0 +1,196 @@ +# NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE + +``` +// (1) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(type, base_type, member...) +// (2) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) +// (3) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...) + +// (4) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(type, base_type, member...) +// (5) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, base_type, member...) +// (6) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, base_type, member...) +``` + +These macros can be used to simplify the serialization/deserialization of derived types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object. + +- Macros 1, 2, and 3 are to be defined **inside** the class/struct to create code for. Like [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md), they can access private members. +- Macros 4, 5, and 6 are to be defined **outside** the class/struct to create code for, but **inside** its namespace. Like [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md), they **cannot** access private members. + +The first parameter is the name of the derived class/struct, the second parameter is the name of the base class/struct and all remaining parameters name the members. The base type **must** be already serializable/deserializable. + +- Macros 1 and 4 will use [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) during deserialization and will throw [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403) if a key is missing in the JSON object. +- Macros 2 and 5 will use [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function default constructs an object and uses its values as the defaults when calling the `value` function. + +Summary: + +| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | +| ------------------------------ | ----------------------- | ---------------------------------------- | ------------------------------------------------------------- | +| | | | **NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE** | +| | | | **NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT** | +| | | | **NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE** | +| | | | **NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE** | +| | | | **NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT** | +| | | | **NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE** | + +## Parameters + +`type` (in) : name of the type (class, struct) to serialize/deserialize + +`base_type` (in) : name of the base type (class, struct) `type` is derived from + +`member` (in) : name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list + +## Default definition + +Macros 1 and 2 add two friend functions to the class which take care of the serialization and deserialization: + +``` +template +friend void to_json(BasicJsonType&, const type&); +template +friend void from_json(const BasicJsonType&, type&); +``` + +Macros 4 and 5 add two functions to the namespace which take care of the serialization and deserialization: + +``` +template +void to_json(BasicJsonType&, const type&); +template +void from_json(const BasicJsonType&, type&); +``` + +Macros 3 and 6 add one function to the namespace, which takes care of the serialization only: + +``` +template +void to_json(BasicJsonType&, const type&); +``` + +In first two cases, they call the `to_json`/`from_json` functions of the base type before serializing/deserializing the members of the derived type: + +``` +class A { /* ... */ }; +class B : public A { /* ... */ }; + +template +void to_json(BasicJsonType& j, const B& b) { + nlohmann::to_json(j, static_cast(b)); + // ... +} + +template +void from_json(const BasicJsonType& j, B& b) { + nlohmann::from_json(j, static_cast(b)); + // ... +} +``` + +In the third case, only `to_json` will be called: + +``` +class A { /* ... */ }; +class B : public A { /* ... */ }; + +template +void to_json(BasicJsonType& j, const B& b) { + nlohmann::to_json(j, static_cast(b)); + // ... +} +``` + +## Notes + +Prerequisites + +- Macros 1, 2, and 3 have the same prerequisites of [NLOHMANN_DEFINE_TYPE_INTRUSIVE](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md). +- Macros 4, 5, and 6 have the same prerequisites of [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md). +- Serialization/deserialization of base types must be defined. + +Implementation limits + +See Implementation limits for [NLOHMANN_DEFINE_TYPE_INTRUSIVE](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) and [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md), respectively. + +## Examples + +NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE + +Consider the following complete example: + +``` +#include +#include +#include + +using nlohmann::json; + +class A +{ + private: + double Aa = 0.0; + double Ab = 0.0; + + public: + A() = default; + A(double a, double b) : Aa(a), Ab(b) {} + NLOHMANN_DEFINE_TYPE_INTRUSIVE(A, Aa, Ab) +}; + +class B : public A +{ + private: + int Ba = 0; + int Bb = 0; + + public: + B() = default; + B(int a, int b, double aa, double ab) : A(aa, ab), Ba(a), Bb(b) {} + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(B, A, Ba, Bb) +}; + +int main() +{ + B example(23, 42, 3.142, 1.777); + json example_json = example; + + std::cout << std::setw(4) << example_json << std::endl; +} +``` + +Output: + +``` +{ + "Aa": 3.142, + "Ab": 1.777, + "Ba": 23, + "Bb": 42 +} +``` + +Notes: + +- `A` and `B` are default-constructible. This is a requirement for using the macro. +- `A` has private members and is not a derived class. Hence, macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is used. +- As `B` is a derived class, `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is not applicable, but `NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE` must be used. +- The macro `NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE` is used *inside* the class use as `NLOHMANN_DEFINE_TYPE_INTRUSIVE`. + +## See also + +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) for similar macros that can be defined *inside* a non-derived type. +- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) for similar macros that can be defined *outside* a non-derived type. +- [Arbitrary Type Conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) for an overview. + +## Version history + +1. Added in version 3.12.0. +1. Added in version 3.12.0. +1. Added in version 3.12.0. +1. Added in version 3.12.0. +1. Added in version 3.12.0. +1. Added in version 3.12.0. diff --git a/api/macros/nlohmann_define_type_intrusive.md b/api/macros/nlohmann_define_type_intrusive.md new file mode 100644 index 000000000..b1ccc3975 --- /dev/null +++ b/api/macros/nlohmann_define_type_intrusive.md @@ -0,0 +1,170 @@ +# NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE + +```cpp +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) // (1) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3) +``` + +These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as +serialization and want to use the member variable names as object keys in that object. The macro is to be defined +**inside** the class/struct to create code for. Unlike +[`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](nlohmann_define_type_non_intrusive.md), it can access private members. The first +parameter is the name of the class/struct, and all remaining parameters name the members. + +1. Will use [`at`](../basic_json/at.md) during deserialization and will throw + [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a key is missing in the JSON object. +2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the + respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function + default constructs an object and uses its values as the defaults when calling the `value` function. +3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required. + +Summary: + +| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | +|------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|-------------------------------------------------------| +|
:octicons-check-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
| **NLOHMANN_DEFINE_TYPE_INTRUSIVE** | +|
:octicons-check-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-check-circle-fill-24:
| **NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT** | +|
:octicons-check-circle-fill-24:
|
:octicons-check-circle-fill-24:
|
:octicons-skip-fill-24:
| **NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE** | + +## Parameters + +`type` (in) +: name of the type (class, struct) to serialize/deserialize + +`member` (in) +: name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list + +## Default definition + +The macros add two friend functions to the class which take care of the serialization and deserialization: + +```cpp +template +friend void to_json(BasicJsonType&, const type&); +template +friend void from_json(const BasicJsonType&, type&); // except (3) +``` + +See the examples below for the concrete generated code. + +## Notes + +!!! info "Prerequisites" + + 1. The type `type` must be default constructible (except (3)). See [How can I use `get()` for non-default + constructible/non-copyable types?][GetNonDefNonCopy] for how to overcome this limitation. + 2. The macro must be used inside the type (class/struct). + +[GetNonDefNonCopy]: ../../features/arbitrary_types.md#how-can-i-use-get-for-non-default-constructiblenon-copyable-types + +!!! warning "Implementation limits" + + - The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types + with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually. + +## Examples + +??? example "Example (1): NLOHMANN_DEFINE_TYPE_INTRUSIVE" + + Consider the following complete example: + + ```cpp hl_lines="22" + --8<-- "examples/nlohmann_define_type_intrusive_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_intrusive_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE` applicable, but not + `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`. + - The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is used _inside_ the class. + - A missing key "age" in the deserialization yields an exception. To fall back to the default value, + `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` can be used. + + The macro is equivalent to: + + ```cpp hl_lines="22 23 24 25 26 27 28 29 30 31 32 33 34 35 36" + --8<-- "examples/nlohmann_define_type_intrusive_explicit.cpp" + ``` + +??? example "Example (2): NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT" + + Consider the following complete example: + + ```cpp hl_lines="22" + --8<-- "examples/nlohmann_define_type_intrusive_with_default_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_intrusive_with_default_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` applicable, + but not `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`. + - The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` is used _inside_ the class. + - A missing key "age" in the deserialization does not yield an exception. Instead, the default value `-1` is used. + + The macro is equivalent to: + + ```cpp hl_lines="22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37" + --8<-- "examples/nlohmann_define_type_intrusive_with_default_explicit.cpp" + ``` + + Note how a default-initialized `person` object is used in the `from_json` to fill missing values. + +??? example "Example (3): NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE" + Consider the following complete example: + + ```cpp hl_lines="22" + --8<-- "examples/nlohmann_define_type_intrusive_only_serialize_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_intrusive_only_serialize_macro.output" + ``` + + Notes: + + - `ns::person` is non-default-constructible. This allows this macro to be used instead of + `NLOHMANN_DEFINE_TYPE_INTRUSIVE` and `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT`. + - `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE` applicable, but not + `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE`. + - The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE` is used _inside_ the class. + + The macro is equivalent to: + + ```cpp hl_lines="22 22 23 24 25 26 27 28" + --8<-- "examples/nlohmann_define_type_intrusive_only_serialize_explicit.cpp" + ``` + +## See also + +- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](nlohmann_define_type_non_intrusive.md) + for a similar macro that can be defined _outside_ the type. +- [NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](nlohmann_define_derived_type.md) for similar macros for + derived types +- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. + +## Version history + +1. Added in version 3.9.0. +2. Added in version 3.11.0. +3. Added in version 3.11.3. diff --git a/api/macros/nlohmann_define_type_intrusive/index.html b/api/macros/nlohmann_define_type_intrusive/index.html index 822a47a38..1a5495661 100644 --- a/api/macros/nlohmann_define_type_intrusive/index.html +++ b/api/macros/nlohmann_define_type_intrusive/index.html @@ -291,4 +291,4 @@ json j = p; std::cout << "serialization: " << j << std::endl; } -

See also

Version history

  1. Added in version 3.9.0.
  2. Added in version 3.11.0.
  3. Added in version 3.11.3.
\ No newline at end of file +

See also

Version history

  1. Added in version 3.9.0.
  2. Added in version 3.11.0.
  3. Added in version 3.11.3.
\ No newline at end of file diff --git a/api/macros/nlohmann_define_type_intrusive/index.md b/api/macros/nlohmann_define_type_intrusive/index.md new file mode 100644 index 000000000..0acc1ab6b --- /dev/null +++ b/api/macros/nlohmann_define_type_intrusive/index.md @@ -0,0 +1,424 @@ +# NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE + +``` +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) // (1) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3) +``` + +These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object. The macro is to be defined **inside** the class/struct to create code for. Unlike [`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md), it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. + +1. Will use [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) during deserialization and will throw [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403) if a key is missing in the JSON object. +1. Will use [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function default constructs an object and uses its values as the defaults when calling the `value` function. +1. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required. + +Summary: + +| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | +| ------------------------------ | ----------------------- | ---------------------------------------- | ------------------------------------------------- | +| | | | **NLOHMANN_DEFINE_TYPE_INTRUSIVE** | +| | | | **NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT** | +| | | | **NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE** | + +## Parameters + +`type` (in) : name of the type (class, struct) to serialize/deserialize + +`member` (in) : name of the member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list + +## Default definition + +The macros add two friend functions to the class which take care of the serialization and deserialization: + +``` +template +friend void to_json(BasicJsonType&, const type&); +template +friend void from_json(const BasicJsonType&, type&); // except (3) +``` + +See the examples below for the concrete generated code. + +## Notes + +Prerequisites + +1. The type `type` must be default constructible (except (3)). See [How can I use `get()` for non-default constructible/non-copyable types?](https://json.nlohmann.me/features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types) for how to overcome this limitation. +1. The macro must be used inside the type (class/struct). + +Implementation limits + +- The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually. + +## Examples + +Example (1): NLOHMANN_DEFINE_TYPE_INTRUSIVE + +Consider the following complete example: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age) +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (const json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} +``` + +Output: + +``` +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found +``` + +Notes: + +- `ns::person` is default-constructible. This is a requirement for using the macro. +- `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE` applicable, but not `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE`. +- The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is used *inside* the class. +- A missing key "age" in the deserialization yields an exception. To fall back to the default value, `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` can be used. + +The macro is equivalent to: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + template + friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t) + { + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; + } + + template + friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t) + { + nlohmann_json_t.name = nlohmann_json_j.at("name"); + nlohmann_json_t.address = nlohmann_json_j.at("address"); + nlohmann_json_t.age = nlohmann_json_j.at("age"); + } +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (const json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} +``` + +Example (2): NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT + +Consider the following complete example: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(person, name, address, age) +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} +``` + +Output: + +``` +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} +``` + +Notes: + +- `ns::person` is default-constructible. This is a requirement for using the macro. +- `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` applicable, but not `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`. +- The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT` is used *inside* the class. +- A missing key "age" in the deserialization does not yield an exception. Instead, the default value `-1` is used. + +The macro is equivalent to: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + template + friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t) + { + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; + } + + template + friend void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t) + { + person nlohmann_json_default_obj; + nlohmann_json_t.name = nlohmann_json_j.value("name", nlohmann_json_default_obj.name); + nlohmann_json_t.address = nlohmann_json_j.value("address", nlohmann_json_default_obj.address); + nlohmann_json_t.age = nlohmann_json_j.value("age", nlohmann_json_default_obj.age); + } +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} +``` + +Note how a default-initialized `person` object is used in the `from_json` to fill missing values. + +Example (3): NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE + +Consider the following complete example: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + // No default constructor + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + NLOHMANN_DEFINE_TYPE_INTRUSIVE(person, name, address, age) +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; +} +``` + +Output: + +``` +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +``` + +Notes: + +- `ns::person` is non-default-constructible. This allows this macro to be used instead of `NLOHMANN_DEFINE_TYPE_INTRUSIVE` and `NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT`. +- `ns::person` has private member variables. This makes `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE` applicable, but not `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE`. +- The macro `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE` is used *inside* the class. + +The macro is equivalent to: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +class person +{ + private: + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + public: + // No default constructor + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} + + template + friend void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t) + { + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; + } +}; +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; +} +``` + +## See also + +- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) for a similar macro that can be defined *outside* the type. +- [NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) for similar macros for derived types +- [Arbitrary Type Conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) for an overview. + +## Version history + +1. Added in version 3.9.0. +1. Added in version 3.11.0. +1. Added in version 3.11.3. diff --git a/api/macros/nlohmann_define_type_non_intrusive.md b/api/macros/nlohmann_define_type_non_intrusive.md new file mode 100644 index 000000000..0b28189d1 --- /dev/null +++ b/api/macros/nlohmann_define_type_non_intrusive.md @@ -0,0 +1,171 @@ +# NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE + +```cpp +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) // (1) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3) +``` + +These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as +serialization and want to use the member variable names as object keys in that object. The macro is to be defined +**outside** the class/struct to create code for, but **inside** its namespace. Unlike +[`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](nlohmann_define_type_intrusive.md), it **cannot** access private members. The first +parameter is the name of the class/struct, and all remaining parameters name the members. + +1. Will use [`at`](../basic_json/at.md) during deserialization and will throw + [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a key is missing in the JSON object. +2. Will use [`value`](../basic_json/value.md) during deserialization and fall back to the default value for the + respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function + default constructs an object and uses its values as the defaults when calling the `value` function. +3. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required. + +Summary: + +| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | +|------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|-------------------------------------------------------| +|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
| **NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE** | +|
:octicons-x-circle-fill-24:
|
:octicons-x-circle-fill-24:
|
:octicons-check-circle-fill-24:
| **NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT** | +|
:octicons-x-circle-fill-24:
|
:octicons-check-circle-fill-24:
|
:octicons-skip-fill-24:
| **NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE** | + +## Parameters + +`type` (in) +: name of the type (class, struct) to serialize/deserialize + +`member` (in) +: name of the (public) member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list + +## Default definition + +The macros add two functions to the namespace which take care of the serialization and deserialization: + +```cpp +template +void to_json(BasicJsonType&, const type&); +template +void from_json(const BasicJsonType&, type&); // except (3) +``` + +See the examples below for the concrete generated code. + +## Notes + +!!! info "Prerequisites" + + 1. The type `type` must be default constructible (except (3). See [How can I use `get()` for non-default constructible/non-copyable types?][GetNonDefNonCopy] + for how to overcome this limitation. + 2. The macro must be used outside the type (class/struct). + 3. The passed members must be public. + +[GetNonDefNonCopy]: ../../features/arbitrary_types.md#how-can-i-use-get-for-non-default-constructiblenon-copyable-types + +!!! warning "Implementation limits" + + - The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types + with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually. + +## Examples + +??? example "Example (1): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE" + + Consider the following complete example: + + ```cpp hl_lines="16" + --8<-- "examples/nlohmann_define_type_non_intrusive_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_non_intrusive_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` applicable. + - The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` is used _outside_ the class, but _inside_ its namespace `ns`. + - A missing key "age" in the deserialization yields an exception. To fall back to the default value, + `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` can be used. + + The macro is equivalent to: + + ```cpp hl_lines="16 17 18 19 20 21 22 23 24 25 26 27 28 29 30" + --8<-- "examples/nlohmann_define_type_non_intrusive_explicit.cpp" + ``` + +??? example "Example (2): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT" + + Consider the following complete example: + + ```cpp hl_lines="21" + --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` + applicable. + - The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` is used _outside_ the class, but _inside_ its + namespace `ns`. + - A missing key "age" in the deserialization does not yield an exception. Instead, the default value `-1` is used. + + The macro is equivalent to: + + ```cpp hl_lines="21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36" + --8<-- "examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp" + ``` + + Note how a default-initialized `person` object is used in the `from_json` to fill missing values. + +??? example "Example (3): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE" + + Consider the following complete example: + + ```cpp hl_lines="16" + --8<-- "examples/nlohmann_define_type_non_intrusive_only_serialize_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_non_intrusive_only_serialize_macro.output" + ``` + + Notes: + + - `ns::person` is non-default-constructible. This allows this macro to be used instead of + `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` and `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`. + - `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` applicable. + - The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` is used _outside_ the class, but _inside_ its namespace `ns`. + + The macro is equivalent to: + + ```cpp hl_lines="16 17 18 19 20 21 22" + --8<-- "examples/nlohmann_define_type_non_intrusive_only_serialize_explicit.cpp" + ``` + +## See also + +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, + NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE](nlohmann_define_type_intrusive.md) + for a similar macro that can be defined _inside_ the type. +- [NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](nlohmann_define_derived_type.md) for similar macros for + derived types +- [Arbitrary Type Conversions](../../features/arbitrary_types.md) for an overview. + +## Version history + +1. Added in version 3.9.0. +2. Added in version 3.11.0. +3. Added in version 3.11.3. diff --git a/api/macros/nlohmann_define_type_non_intrusive/index.html b/api/macros/nlohmann_define_type_non_intrusive/index.html index 731b7824e..dd08ee7cc 100644 --- a/api/macros/nlohmann_define_type_non_intrusive/index.html +++ b/api/macros/nlohmann_define_type_non_intrusive/index.html @@ -259,4 +259,4 @@ json j = p; std::cout << "serialization: " << j << std::endl; } -

See also

Version history

  1. Added in version 3.9.0.
  2. Added in version 3.11.0.
  3. Added in version 3.11.3.
\ No newline at end of file +

See also

Version history

  1. Added in version 3.9.0.
  2. Added in version 3.11.0.
  3. Added in version 3.11.3.
\ No newline at end of file diff --git a/api/macros/nlohmann_define_type_non_intrusive/index.md b/api/macros/nlohmann_define_type_non_intrusive/index.md new file mode 100644 index 000000000..2751691bd --- /dev/null +++ b/api/macros/nlohmann_define_type_non_intrusive/index.md @@ -0,0 +1,393 @@ +# NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE + +``` +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) // (1) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(type, member...) // (3) +``` + +These macros can be used to simplify the serialization/deserialization of types if you want to use a JSON object as serialization and want to use the member variable names as object keys in that object. The macro is to be defined **outside** the class/struct to create code for, but **inside** its namespace. Unlike [`NLOHMANN_DEFINE_TYPE_INTRUSIVE`](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md), it **cannot** access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. + +1. Will use [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) during deserialization and will throw [`out_of_range.403`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range403) if a key is missing in the JSON object. +1. Will use [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) during deserialization and fall back to the default value for the respective type of the member variable if a key in the JSON object is missing. The generated `from_json()` function default constructs an object and uses its values as the defaults when calling the `value` function. +1. Only defines the serialization. Useful in cases when the type does not have a default constructor and only serialization is required. + +Summary: + +| Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | +| ------------------------------ | ----------------------- | ---------------------------------------- | ----------------------------------------------------- | +| | | | **NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE** | +| | | | **NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT** | +| | | | **NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE** | + +## Parameters + +`type` (in) : name of the type (class, struct) to serialize/deserialize + +`member` (in) : name of the (public) member variable to serialize/deserialize; up to 63 members can be given as a comma-separated list + +## Default definition + +The macros add two functions to the namespace which take care of the serialization and deserialization: + +``` +template +void to_json(BasicJsonType&, const type&); +template +void from_json(const BasicJsonType&, type&); // except (3) +``` + +See the examples below for the concrete generated code. + +## Notes + +Prerequisites + +1. The type `type` must be default constructible (except (3). See [How can I use `get()` for non-default constructible/non-copyable types?](https://json.nlohmann.me/features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types) for how to overcome this limitation. +1. The macro must be used outside the type (class/struct). +1. The passed members must be public. + +Implementation limits + +- The current implementation is limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually. + +## Examples + +Example (1): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE + +Consider the following complete example: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age) +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (const json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} +``` + +Output: + +``` +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found +``` + +Notes: + +- `ns::person` is default-constructible. This is a requirement for using the macro. +- `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` applicable. +- The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` is used *outside* the class, but *inside* its namespace `ns`. +- A missing key "age" in the deserialization yields an exception. To fall back to the default value, `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` can be used. + +The macro is equivalent to: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +template +void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t) +{ + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; +} + +template +void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t) +{ + nlohmann_json_t.name = nlohmann_json_j.at("name"); + nlohmann_json_t.address = nlohmann_json_j.at("address"); + nlohmann_json_t.age = nlohmann_json_j.at("age"); +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.get(); + } + catch (const json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} +``` + +Example (2): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT + +Consider the following complete example: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(person, name, address, age) +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} +``` + +Output: + +``` +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} +``` + +Notes: + +- `ns::person` is default-constructible. This is a requirement for using the macro. +- `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` applicable. +- The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT` is used *outside* the class, but *inside* its namespace `ns`. +- A missing key "age" in the deserialization does not yield an exception. Instead, the default value `-1` is used. + +The macro is equivalent to: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name = "John Doe"; + std::string address = "123 Fake St"; + int age = -1; + + person() = default; + person(std::string name_, std::string address_, int age_) + : name(std::move(name_)), address(std::move(address_)), age(age_) + {} +}; + +template +void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t) +{ + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; +} + +template +void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t) +{ + person nlohmann_json_default_obj; + nlohmann_json_t.name = nlohmann_json_j.value("name", nlohmann_json_default_obj.name); + nlohmann_json_t.address = nlohmann_json_j.value("address", nlohmann_json_default_obj.address); + nlohmann_json_t.age = nlohmann_json_j.value("age", nlohmann_json_default_obj.age); +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"address": "742 Evergreen Terrace", "age": 40, "name": "Homer Simpson"})"_json; + auto p2 = j2.get(); + + // incomplete deserialization: + json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json; + auto p3 = j3.get(); + std::cout << "roundtrip: " << json(p3) << std::endl; +} +``` + +Note how a default-initialized `person` object is used in the `from_json` to fill missing values. + +Example (3): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE + +Consider the following complete example: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(person, name, address, age) +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; +} +``` + +Output: + +``` +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +``` + +Notes: + +- `ns::person` is non-default-constructible. This allows this macro to be used instead of `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` and `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT`. +- `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` applicable. +- The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` is used *outside* the class, but *inside* its namespace `ns`. + +The macro is equivalent to: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +template +void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t) +{ + nlohmann_json_j["name"] = nlohmann_json_t.name; + nlohmann_json_j["address"] = nlohmann_json_t.address; + nlohmann_json_j["age"] = nlohmann_json_t.age; +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; +} +``` + +## See also + +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) for a similar macro that can be defined *inside* the type. +- [NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) for similar macros for derived types +- [Arbitrary Type Conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) for an overview. + +## Version history + +1. Added in version 3.9.0. +1. Added in version 3.11.0. +1. Added in version 3.11.3. diff --git a/api/macros/nlohmann_define_type_with_names.md b/api/macros/nlohmann_define_type_with_names.md new file mode 100644 index 000000000..d8640496a --- /dev/null +++ b/api/macros/nlohmann_define_type_with_names.md @@ -0,0 +1,78 @@ +

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, + NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, + NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES

+ +```cpp +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, "json_member_name", member...) +``` + +These macros can be used in case you want to use the custom names for the member variables in the resulting JSON. +They behave exactly as their non-`WITH_NAMES` counterparts, but require an additional parameter for each member variable +which will be used in JSON. Both serialization and deserialization will only use the custom names for JSON, the names of +the member variables themselves will be ignored. + +Using the named conversion macros will halve the maximum number of member variables from 63 to 31. + +For further information please refer to the corresponding macros without `WITH_NAMES`. + +## Parameters + +`type` (in) +: name of the type (class, struct) to serialize/deserialize + +`base_type` (in) +: name of the base type (class, struct) `type` is derived from (used only in `DEFINE_DERIVED_TYPE` macros) + +`json_member_name` (in) +: the string that will be used as the name for the next value + +`member` (in) +: name of the member variable to serialize/deserialize + +## Examples + +??? example "Example (1): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES" + + Consider the following complete example: + + ```cpp hl_lines="16" + --8<-- "examples/nlohmann_define_type_non_intrusive_with_names_macro.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_define_type_non_intrusive_with_names_macro.output" + ``` + + Notes: + + - `ns::person` is default-constructible. This is a requirement for using the macro. + - `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES` applicable. + - The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES` is used _outside_ the class, but _inside_ its namespace `ns`. + - A missing key "age" in the deserialization yields an exception. To fall back to the default value, + `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES` can be used. + + The macro is equivalent to: + + ```cpp hl_lines="16 17 18 19 20 21 22 23 24 25 26 27 28" + --8<-- "examples/nlohmann_define_type_non_intrusive_with_names_explicit.cpp" + ``` + +## Version history + +1. Added in version 3.12.x. diff --git a/api/macros/nlohmann_define_type_with_names/index.html b/api/macros/nlohmann_define_type_with_names/index.html index 9230fb1f0..ff980fda9 100644 --- a/api/macros/nlohmann_define_type_with_names/index.html +++ b/api/macros/nlohmann_define_type_with_names/index.html @@ -108,4 +108,4 @@ std::cout << "deserialization failed: " << e.what() << std::endl; } } -

Version history

  1. Added in version 3.12.x.
\ No newline at end of file +

Version history

  1. Added in version 3.12.x.
\ No newline at end of file diff --git a/api/macros/nlohmann_define_type_with_names/index.md b/api/macros/nlohmann_define_type_with_names/index.md new file mode 100644 index 000000000..8201bb339 --- /dev/null +++ b/api/macros/nlohmann_define_type_with_names/index.md @@ -0,0 +1,160 @@ +# NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES + +``` +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES(type, base_type, "json_member_name", member...) +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES(type, base_type, "json_member_name", member...) +``` + +These macros can be used in case you want to use the custom names for the member variables in the resulting JSON. They behave exactly as their non-`WITH_NAMES` counterparts, but require an additional parameter for each member variable which will be used in JSON. Both serialization and deserialization will only use the custom names for JSON, the names of the member variables themselves will be ignored. + +Using the named conversion macros will halve the maximum number of member variables from 63 to 31. + +For further information please refer to the corresponding macros without `WITH_NAMES`. + +## Parameters + +`type` (in) : name of the type (class, struct) to serialize/deserialize + +`base_type` (in) : name of the base type (class, struct) `type` is derived from (used only in `DEFINE_DERIVED_TYPE` macros) + +`json_member_name` (in) : the string that will be used as the name for the next value + +`member` (in) : name of the member variable to serialize/deserialize + +## Examples + +Example (1): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES + +Consider the following complete example: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES(person, "json_name", name, "json_address", address, "json_age", age) +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"json_address": "742 Evergreen Terrace", "json_age": 40, "json_name": "Homer Simpson"})"_json; + auto p2 = j2.template get(); + + // incomplete deserialization: + json j3 = R"({"json_address": "742 Evergreen Terrace", "json_name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.template get(); + } + catch (const json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} +``` + +Output: + +``` +serialization: {"json_address":"744 Evergreen Terrace","json_age":60,"json_name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'json_age' not found +``` + +Notes: + +- `ns::person` is default-constructible. This is a requirement for using the macro. +- `ns::person` has only public member variables. This makes `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES` applicable. +- The macro `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES` is used *outside* the class, but *inside* its namespace `ns`. +- A missing key "age" in the deserialization yields an exception. To fall back to the default value, `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES` can be used. + +The macro is equivalent to: + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +template ::value, int> = 0> +void to_json(BasicJsonType& nlohmann_json_j, const person& nlohmann_json_t) +{ + nlohmann_json_j["json_name"] = nlohmann_json_t.name; + nlohmann_json_j["json_address"] = nlohmann_json_t.address; + nlohmann_json_j["json_age"] = nlohmann_json_t.age; +} + +template ::value, int> = 0> +void from_json(const BasicJsonType& nlohmann_json_j, person& nlohmann_json_t) +{ + nlohmann_json_j.at("json_name").get_to(nlohmann_json_t.name); + nlohmann_json_j.at("json_address").get_to(nlohmann_json_t.address); + nlohmann_json_j.at("json_age").get_to(nlohmann_json_t.age); +} +} // namespace ns + +int main() +{ + ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + + // serialization: person -> json + json j = p; + std::cout << "serialization: " << j << std::endl; + + // deserialization: json -> person + json j2 = R"({"json_address": "742 Evergreen Terrace", "json_age": 40, "json_name": "Homer Simpson"})"_json; + auto p2 = j2.template get(); + + // incomplete deserialization: + json j3 = R"({"json_address": "742 Evergreen Terrace", "json_name": "Maggie Simpson"})"_json; + try + { + auto p3 = j3.template get(); + } + catch (const json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} +``` + +## Version history + +1. Added in version 3.12.x. diff --git a/api/macros/nlohmann_json_namespace.md b/api/macros/nlohmann_json_namespace.md new file mode 100644 index 000000000..5c54dba52 --- /dev/null +++ b/api/macros/nlohmann_json_namespace.md @@ -0,0 +1,41 @@ +# NLOHMANN_JSON_NAMESPACE + +```cpp +#define NLOHMANN_JSON_NAMESPACE /* value */ +``` + +This macro evaluates to the full name of the `nlohmann` namespace. + +## Default definition + +The default value consists of the root namespace (`nlohmann`) and an inline ABI namespace. See +[`nlohmann` Namespace](../../features/namespace.md#structure) for details. + +When the macro is not defined, the library will define it to its default value. Overriding this value has no effect on +the library. + +## Examples + +??? example + + The example shows how to use `NLOHMANN_JSON_NAMESPACE` instead of just `nlohmann`, as well as how to output the value + of `NLOHMANN_JSON_NAMESPACE`. + + ```cpp + --8<-- "examples/nlohmann_json_namespace.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_namespace.output" + ``` + +## See also + +- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](nlohmann_json_namespace_begin.md) +- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](nlohmann_json_namespace_no_version.md) + +## Version history + +- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. diff --git a/api/macros/nlohmann_json_namespace/index.html b/api/macros/nlohmann_json_namespace/index.html index f8d0dffd8..3a27ef57c 100644 --- a/api/macros/nlohmann_json_namespace/index.html +++ b/api/macros/nlohmann_json_namespace/index.html @@ -14,4 +14,4 @@ std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl; }

Output:

nlohmann::json_abi_v3_12_0
-

See also

Version history

  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.
\ No newline at end of file diff --git a/api/macros/nlohmann_json_namespace/index.md b/api/macros/nlohmann_json_namespace/index.md new file mode 100644 index 000000000..5e8b7b5e9 --- /dev/null +++ b/api/macros/nlohmann_json_namespace/index.md @@ -0,0 +1,51 @@ +# NLOHMANN_JSON_NAMESPACE + +``` +#define NLOHMANN_JSON_NAMESPACE /* value */ +``` + +This macro evaluates to the full name of the `nlohmann` namespace. + +## Default definition + +The default value consists of the root namespace (`nlohmann`) and an inline ABI namespace. See [`nlohmann` Namespace](https://json.nlohmann.me/features/namespace/#structure) for details. + +When the macro is not defined, the library will define it to its default value. Overriding this value has no effect on the library. + +## Examples + +Example + +The example shows how to use `NLOHMANN_JSON_NAMESPACE` instead of just `nlohmann`, as well as how to output the value of `NLOHMANN_JSON_NAMESPACE`. + +``` +#include +#include + +// possible use case: use NLOHMANN_JSON_NAMESPACE instead of nlohmann +using json = NLOHMANN_JSON_NAMESPACE::json; + +// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal +#define Q(x) #x +#define QUOTE(x) Q(x) + +int main() +{ + std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl; +} +``` + +Output: + +``` +nlohmann::json_abi_v3_12_0 +``` + +## See also + +- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/index.md) +- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/index.md) + +## Version history + +- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. diff --git a/api/macros/nlohmann_json_namespace_begin.md b/api/macros/nlohmann_json_namespace_begin.md new file mode 100644 index 000000000..118fba63a --- /dev/null +++ b/api/macros/nlohmann_json_namespace_begin.md @@ -0,0 +1,61 @@ +# NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END + +```cpp +#define NLOHMANN_JSON_NAMESPACE_BEGIN /* value */ // (1) +#define NLOHMANN_JSON_NAMESPACE_END /* value */ // (2) +``` + +These macros can be used to open and close the `nlohmann` namespace. See +[`nlohmann` Namespace](../../features/namespace.md#structure) for details. + +1. Opens the namespace. +2. Closes the namespace. + +## Default definition + +The default definitions open and close the `nlohmann` namespace. The precise definition of +[`NLOHMANN_JSON_NAMESPACE_BEGIN`] varies as described [here](../../features/namespace.md#structure). + +1. Default definition of `NLOHMANN_JSON_NAMESPACE_BEGIN`: + + ```cpp + namespace nlohmann + { + inline namespace json_abi_v3_12_0 + { + ``` + +2. Default definition of `NLOHMANN_JSON_NAMESPACE_END`: + ```cpp + } // namespace json_abi_v3_12_0 + } // namespace nlohmann + ``` + +When these macros are not defined, the library will define them to their default definitions. + +## Examples + +??? example + + The example shows how to use `NLOHMANN_JSON_NAMESPACE_BEGIN`/`NLOHMANN_JSON_NAMESPACE_END` from the + [How do I convert third-party types?](../../features/arbitrary_types.md#how-do-i-convert-third-party-types) page. + + ```cpp + --8<-- "examples/nlohmann_json_namespace_begin.c++17.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_namespace_begin.c++17.output" + ``` + +## See also + +- [`nlohmann` Namespace](../../features/namespace.md) +- [NLOHMANN_JSON_NAMESPACE](nlohmann_json_namespace.md) +- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](nlohmann_json_namespace_no_version.md) + +## Version history + +- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. diff --git a/api/macros/nlohmann_json_namespace_begin/index.html b/api/macros/nlohmann_json_namespace_begin/index.html index 0c9a01b6d..2fee15355 100644 --- a/api/macros/nlohmann_json_namespace_begin/index.html +++ b/api/macros/nlohmann_json_namespace_begin/index.html @@ -40,4 +40,4 @@ std::cout << j << std::endl; }

Output:

[1,null]
-

See also

Version history

  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.
\ No newline at end of file diff --git a/api/macros/nlohmann_json_namespace_begin/index.md b/api/macros/nlohmann_json_namespace_begin/index.md new file mode 100644 index 000000000..a2ca535e9 --- /dev/null +++ b/api/macros/nlohmann_json_namespace_begin/index.md @@ -0,0 +1,91 @@ +# NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END + +``` +#define NLOHMANN_JSON_NAMESPACE_BEGIN /* value */ // (1) +#define NLOHMANN_JSON_NAMESPACE_END /* value */ // (2) +``` + +These macros can be used to open and close the `nlohmann` namespace. See [`nlohmann` Namespace](https://json.nlohmann.me/features/namespace/#structure) for details. + +1. Opens the namespace. +1. Closes the namespace. + +## Default definition + +The default definitions open and close the `nlohmann` namespace. The precise definition of \[`NLOHMANN_JSON_NAMESPACE_BEGIN`\] varies as described [here](https://json.nlohmann.me/features/namespace/#structure). + +1. Default definition of `NLOHMANN_JSON_NAMESPACE_BEGIN`: + + ``` + namespace nlohmann + { + inline namespace json_abi_v3_12_0 + { + ``` + +1. Default definition of `NLOHMANN_JSON_NAMESPACE_END`: + + ``` + } // namespace json_abi_v3_12_0 + } // namespace nlohmann + ``` + +When these macros are not defined, the library will define them to their default definitions. + +## Examples + +Example + +The example shows how to use `NLOHMANN_JSON_NAMESPACE_BEGIN`/`NLOHMANN_JSON_NAMESPACE_END` from the [How do I convert third-party types?](https://json.nlohmann.me/features/arbitrary_types/#how-do-i-convert-third-party-types) page. + +``` +#include +#include +#include + +// partial specialization (see https://json.nlohmann.me/features/arbitrary_types/) +NLOHMANN_JSON_NAMESPACE_BEGIN +template +struct adl_serializer> +{ + static void to_json(json& j, const std::optional& opt) + { + if (opt == std::nullopt) + { + j = nullptr; + } + else + { + j = *opt; + } + } +}; +NLOHMANN_JSON_NAMESPACE_END + +int main() +{ + std::optional o1 = 1; + std::optional o2 = std::nullopt; + + NLOHMANN_JSON_NAMESPACE::json j; + j.push_back(o1); + j.push_back(o2); + std::cout << j << std::endl; +} +``` + +Output: + +``` +[1,null] +``` + +## See also + +- [`nlohmann` Namespace](https://json.nlohmann.me/features/namespace/index.md) +- [NLOHMANN_JSON_NAMESPACE](https://json.nlohmann.me/api/macros/nlohmann_json_namespace/index.md) +- [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/index.md) + +## Version history + +- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. diff --git a/api/macros/nlohmann_json_namespace_no_version.md b/api/macros/nlohmann_json_namespace_no_version.md new file mode 100644 index 000000000..9e2a52d04 --- /dev/null +++ b/api/macros/nlohmann_json_namespace_no_version.md @@ -0,0 +1,45 @@ +# NLOHMANN_JSON_NAMESPACE_NO_VERSION + +```cpp +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */ +``` + +If defined to `1`, the version component is omitted from the inline namespace. See +[`nlohmann` Namespace](../../features/namespace.md#structure) for details. + +## Default definition + +The default value is `0`. + +```cpp +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Examples + +??? example + + The example shows how to use `NLOHMANN_JSON_NAMESPACE_NO_VERSION` to disable the version component of the inline + namespace. + + ```cpp + --8<-- "examples/nlohmann_json_namespace_no_version.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_namespace_no_version.output" + ``` + +## See also + +- [`nlohmann` Namespace](../../features/namespace.md) +- [`NLOHMANN_JSON_NAMESPACE`](nlohmann_json_namespace.md) +- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](nlohmann_json_namespace_begin.md) + +## Version history + +- Added in version 3.11.2. diff --git a/api/macros/nlohmann_json_namespace_no_version/index.html b/api/macros/nlohmann_json_namespace_no_version/index.html index 57e5ccab0..5d7780a83 100644 --- a/api/macros/nlohmann_json_namespace_no_version/index.html +++ b/api/macros/nlohmann_json_namespace_no_version/index.html @@ -14,4 +14,4 @@ std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl; }

Output:

nlohmann::json_abi
-

See also

Version history

  • Added in version 3.11.2.
\ No newline at end of file +

See also

Version history

  • Added in version 3.11.2.
\ No newline at end of file diff --git a/api/macros/nlohmann_json_namespace_no_version/index.md b/api/macros/nlohmann_json_namespace_no_version/index.md new file mode 100644 index 000000000..fe39ac826 --- /dev/null +++ b/api/macros/nlohmann_json_namespace_no_version/index.md @@ -0,0 +1,55 @@ +# NLOHMANN_JSON_NAMESPACE_NO_VERSION + +``` +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */ +``` + +If defined to `1`, the version component is omitted from the inline namespace. See [`nlohmann` Namespace](https://json.nlohmann.me/features/namespace/#structure) for details. + +## Default definition + +The default value is `0`. + +``` +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +``` + +When the macro is not defined, the library will define it to its default value. + +## Examples + +Example + +The example shows how to use `NLOHMANN_JSON_NAMESPACE_NO_VERSION` to disable the version component of the inline namespace. + +``` +#include + +#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 1 +#include + +// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal +#define Q(x) #x +#define QUOTE(x) Q(x) + +int main() +{ + std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl; +} +``` + +Output: + +``` +nlohmann::json_abi +``` + +## See also + +- [`nlohmann` Namespace](https://json.nlohmann.me/features/namespace/index.md) +- [`NLOHMANN_JSON_NAMESPACE`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace/index.md) +- [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/index.md) + +## Version history + +- Added in version 3.11.2. diff --git a/api/macros/nlohmann_json_serialize_enum.md b/api/macros/nlohmann_json_serialize_enum.md new file mode 100644 index 000000000..915a20a5f --- /dev/null +++ b/api/macros/nlohmann_json_serialize_enum.md @@ -0,0 +1,86 @@ +# NLOHMANN_JSON_SERIALIZE_ENUM + +```cpp +#define NLOHMANN_JSON_SERIALIZE_ENUM(type, conversion...) +``` + +By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If +an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be +undefined or a different enum value than was originally intended. + +The `NLOHMANN_JSON_SERIALIZE_ENUM` allows to define a user-defined serialization for every enumerator. + +## Parameters + +`type` (in) +: name of the enum to serialize/deserialize + +`conversion` (in) +: a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list + +## Default definition + +The macro adds two functions to the namespace which take care of the serialization and deserialization: + +```cpp +template +inline void to_json(BasicJsonType& j, const type& e); +template +inline void from_json(const BasicJsonType& j, type& e); +``` + +## Notes + +!!! info "Prerequisites" + + The macro must be used inside the namespace of the enum. + +!!! important "Important notes" + + - When using [`get()`](../basic_json/get.md), undefined JSON values will default to the first specified + conversion. Select this default pair carefully. See example 1 below. + - If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the + list will be returned when converting to or from JSON. See example 2 below. + +## Examples + +??? example "Example 1: Basic usage" + + The example shows how `NLOHMANN_JSON_SERIALIZE_ENUM` can be used to serialize/deserialize both classical enums and + C++11 enum classes: + + ```cpp hl_lines="16 17 18 19 20 21 22 29 30 31 32 33" + --8<-- "examples/nlohmann_json_serialize_enum.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_serialize_enum.output" + ``` + +??? example "Example 2: Multiple conversions for one enumerator" + + The example shows how to use multiple conversions for a single enumerator. In the example, `Color::red` will always + be *serialized* to `"red"`, because the first occurring conversion. The second conversion, however, offers an + alternative *deserialization* from `"rot"` to `Color::red`. + + ```cpp hl_lines="17" + --8<-- "examples/nlohmann_json_serialize_enum_2.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_serialize_enum_2.output" + ``` + +## See also + +- [Specializing enum conversion](../../features/enum_conversion.md) +- [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](./nlohmann_json_serialize_enum_strict.md) +- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md) + +## Version history + +Added in version 3.4.0. diff --git a/api/macros/nlohmann_json_serialize_enum/index.html b/api/macros/nlohmann_json_serialize_enum/index.html index 8d95ac076..74c0edabe 100644 --- a/api/macros/nlohmann_json_serialize_enum/index.html +++ b/api/macros/nlohmann_json_serialize_enum/index.html @@ -101,4 +101,4 @@

Output:

0 -> "red"
 "rot" -> 0
 "red" -> 0
-

See also

Version history

Added in version 3.4.0.

\ No newline at end of file +

See also

Version history

Added in version 3.4.0.

\ No newline at end of file diff --git a/api/macros/nlohmann_json_serialize_enum/index.md b/api/macros/nlohmann_json_serialize_enum/index.md new file mode 100644 index 000000000..ddea99c02 --- /dev/null +++ b/api/macros/nlohmann_json_serialize_enum/index.md @@ -0,0 +1,171 @@ +# NLOHMANN_JSON_SERIALIZE_ENUM + +``` +#define NLOHMANN_JSON_SERIALIZE_ENUM(type, conversion...) +``` + +By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be undefined or a different enum value than was originally intended. + +The `NLOHMANN_JSON_SERIALIZE_ENUM` allows to define a user-defined serialization for every enumerator. + +## Parameters + +`type` (in) : name of the enum to serialize/deserialize + +`conversion` (in) : a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list + +## Default definition + +The macro adds two functions to the namespace which take care of the serialization and deserialization: + +``` +template +inline void to_json(BasicJsonType& j, const type& e); +template +inline void from_json(const BasicJsonType& j, type& e); +``` + +## Notes + +Prerequisites + +The macro must be used inside the namespace of the enum. + +Important notes + +- When using [`get()`](https://json.nlohmann.me/api/basic_json/get/index.md), undefined JSON values will default to the first specified conversion. Select this default pair carefully. See example 1 below. +- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the list will be returned when converting to or from JSON. See example 2 below. + +## Examples + +Example 1: Basic usage + +The example shows how `NLOHMANN_JSON_SERIALIZE_ENUM` can be used to serialize/deserialize both classical enums and C++11 enum classes: + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +enum TaskState +{ + TS_STOPPED, + TS_RUNNING, + TS_COMPLETED, + TS_INVALID = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(TaskState, +{ + { TS_INVALID, nullptr }, + { TS_STOPPED, "stopped" }, + { TS_RUNNING, "running" }, + { TS_COMPLETED, "completed" } +}) + +enum class Color +{ + red, green, blue, unknown +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(Color, +{ + { Color::unknown, "unknown" }, { Color::red, "red" }, + { Color::green, "green" }, { Color::blue, "blue" } +}) +} // namespace ns + +int main() +{ + // serialization + json j_stopped = ns::TS_STOPPED; + json j_red = ns::Color::red; + std::cout << "ns::TS_STOPPED -> " << j_stopped + << ", ns::Color::red -> " << j_red << std::endl; + + // deserialization + json j_running = "running"; + json j_blue = "blue"; + auto running = j_running.get(); + auto blue = j_blue.get(); + std::cout << j_running << " -> " << running + << ", " << j_blue << " -> " << static_cast(blue) << std::endl; + + // deserializing undefined JSON value to enum + // (where the first map entry above is the default) + json j_pi = 3.14; + auto invalid = j_pi.get(); + auto unknown = j_pi.get(); + std::cout << j_pi << " -> " << invalid << ", " + << j_pi << " -> " << static_cast(unknown) << std::endl; +} +``` + +Output: + +``` +ns::TS_STOPPED -> "stopped", ns::Color::red -> "red" +"running" -> 1, "blue" -> 2 +3.14 -> -1, 3.14 -> 3 +``` + +Example 2: Multiple conversions for one enumerator + +The example shows how to use multiple conversions for a single enumerator. In the example, `Color::red` will always be *serialized* to `"red"`, because the first occurring conversion. The second conversion, however, offers an alternative *deserialization* from `"rot"` to `Color::red`. + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +enum class Color +{ + red, green, blue, unknown +}; + +NLOHMANN_JSON_SERIALIZE_ENUM(Color, +{ + { Color::unknown, "unknown" }, { Color::red, "red" }, + { Color::green, "green" }, { Color::blue, "blue" }, + { Color::red, "rot" } // a second conversion for Color::red +}) +} + +int main() +{ + // serialization + json j_red = ns::Color::red; + std::cout << static_cast(ns::Color::red) << " -> " << j_red << std::endl; + + // deserialization + json j_rot = "rot"; + auto rot = j_rot.get(); + auto red = j_red.get(); + std::cout << j_rot << " -> " << static_cast(rot) << std::endl; + std::cout << j_red << " -> " << static_cast(red) << std::endl; +} +``` + +Output: + +``` +0 -> "red" +"rot" -> 0 +"red" -> 0 +``` + +## See also + +- [Specializing enum conversion](https://json.nlohmann.me/features/enum_conversion/index.md) +- [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/index.md) +- [`JSON_DISABLE_ENUM_SERIALIZATION`](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md) + +## Version history + +Added in version 3.4.0. diff --git a/api/macros/nlohmann_json_serialize_enum_strict.md b/api/macros/nlohmann_json_serialize_enum_strict.md new file mode 100644 index 000000000..7b100748b --- /dev/null +++ b/api/macros/nlohmann_json_serialize_enum_strict.md @@ -0,0 +1,105 @@ +# NLOHMANN_JSON_SERIALIZE_ENUM_STRICT + +```cpp +#define NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(type, conversion...) +``` + +By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If +an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be +undefined or a different enum value than was originally intended. + +`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` allows to define a user-defined serialization for every enumerator that +throws an exception on undefined input. + +## Parameters + +`type` (in) +: name of the enum to serialize/deserialize + +`conversion` (in) +: a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list + +## Default definition + +The macro adds two functions to the namespace which take care of the serialization and deserialization: + +```cpp +template +inline void to_json(BasicJsonType& j, const type& e); +template +inline void from_json(const BasicJsonType& j, type& e); +``` + +## Notes + +!!! info "Prerequisites" + + The macro must be used inside the namespace of the enum. + +!!! important "Important notes" + + - Undefined input throws [`out_of_range.410`](../../home/exceptions.md#jsonexceptionout_of_range410) in both + directions: when serializing an enum value not listed in the conversions, and when deserializing (e.g., via + [`get()`](../basic_json/get.md)) a JSON value that matches no conversion; example: + `"enum value out of range for "`. + - If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the + list will be returned when converting to or from JSON. See example 2 below. + +## Examples + +??? example "Example 1: Basic usage" + + The example shows how `NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` can be used to serialize/deserialize both classical enums and + C++11 enum classes: + + ```cpp hl_lines="16 17 18 19 20 21 22 29 30 31 32 33" + --8<-- "examples/nlohmann_json_serialize_enum_strict.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_serialize_enum_strict.output" + ``` + +??? example "Example 2: Multiple conversions for one enumerator" + + The example shows how to use multiple conversions for a single enumerator. In the example, `Color::red` will always + be *serialized* to `"red"`, because the first occurring conversion. The second conversion, however, offers an + alternative *deserialization* from `"rot"` to `Color::red`. + + ```cpp hl_lines="17" + --8<-- "examples/nlohmann_json_serialize_enum_strict_2.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_serialize_enum_strict_2.output" + ``` + +??? example "Example 3: exceptions on invalid serialization" + + The example shows how an invalid serialization causes an exception to be thrown. In the example, + Color::unknown is not defined in the mapping used to call `NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` + so causes an exception when used to serialize. Similarly, "what" does not refer to an enum + value so also causes an exception when deserialization is attempted. + + ```cpp hl_lines="14 32 33 43 44 45" + --8<-- "examples/nlohmann_json_serialize_enum_strict_err.cpp" + ``` + + Output: + ```json + --8<-- "examples/nlohmann_json_serialize_enum_strict_err.output" + ``` + +## See also + +- [Specializing enum conversion](../../features/enum_conversion.md) +- [`NLOHMANN_JSON_SERIALIZE_ENUM`](./nlohmann_json_serialize_enum.md) +- [`JSON_DISABLE_ENUM_SERIALIZATION`](json_disable_enum_serialization.md) + +## Version history + +Added in version 3.12.x. diff --git a/api/macros/nlohmann_json_serialize_enum_strict/index.html b/api/macros/nlohmann_json_serialize_enum_strict/index.html index d1234efb3..0036b33f8 100644 --- a/api/macros/nlohmann_json_serialize_enum_strict/index.html +++ b/api/macros/nlohmann_json_serialize_enum_strict/index.html @@ -148,4 +148,4 @@ }

Output:

deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color
 deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color: "what"
-

See also

Version history

Added in version 3.12.x.

\ No newline at end of file +

See also

Version history

Added in version 3.12.x.

\ No newline at end of file diff --git a/api/macros/nlohmann_json_serialize_enum_strict/index.md b/api/macros/nlohmann_json_serialize_enum_strict/index.md new file mode 100644 index 000000000..50b5111bb --- /dev/null +++ b/api/macros/nlohmann_json_serialize_enum_strict/index.md @@ -0,0 +1,230 @@ +# NLOHMANN_JSON_SERIALIZE_ENUM_STRICT + +``` +#define NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(type, conversion...) +``` + +By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If an enum is modified or re-ordered after data has been serialized to JSON, the later deserialized JSON data may be undefined or a different enum value than was originally intended. + +`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` allows to define a user-defined serialization for every enumerator that throws an exception on undefined input. + +## Parameters + +`type` (in) : name of the enum to serialize/deserialize + +`conversion` (in) : a pair of an enumerator and a JSON serialization; arbitrary pairs can be given as a comma-separated list + +## Default definition + +The macro adds two functions to the namespace which take care of the serialization and deserialization: + +``` +template +inline void to_json(BasicJsonType& j, const type& e); +template +inline void from_json(const BasicJsonType& j, type& e); +``` + +## Notes + +Prerequisites + +The macro must be used inside the namespace of the enum. + +Important notes + +- Undefined input throws [`out_of_range.410`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range410) in both directions: when serializing an enum value not listed in the conversions, and when deserializing (e.g., via [`get()`](https://json.nlohmann.me/api/basic_json/get/index.md)) a JSON value that matches no conversion; example: `"enum value out of range for "`. +- If an enum or JSON value is specified in multiple conversions, the first matching conversion from the top of the list will be returned when converting to or from JSON. See example 2 below. + +## Examples + +Example 1: Basic usage + +The example shows how `NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` can be used to serialize/deserialize both classical enums and C++11 enum classes: + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +enum TaskState +{ + TS_STOPPED, + TS_RUNNING, + TS_COMPLETED, + TS_INVALID = -1 +}; + +NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(TaskState, +{ + { TS_INVALID, nullptr }, + { TS_STOPPED, "stopped" }, + { TS_RUNNING, "running" }, + { TS_COMPLETED, "completed" } +}) + +enum class Color +{ + red, green, blue, unknown +}; + +NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color, +{ + { Color::unknown, "unknown" }, { Color::red, "red" }, + { Color::green, "green" }, { Color::blue, "blue" } +}) +} // namespace ns + +int main() +{ + // serialization + json j_stopped = ns::TS_STOPPED; + json j_red = ns::Color::red; + std::cout << "ns::TS_STOPPED -> " << j_stopped + << ", ns::Color::red -> " << j_red << std::endl; + + // deserialization + json j_running = "running"; + json j_blue = "blue"; + auto running = j_running.get(); + auto blue = j_blue.get(); + std::cout << j_running << " -> " << running + << ", " << j_blue << " -> " << static_cast(blue) << std::endl; + +} +``` + +Output: + +``` +ns::TS_STOPPED -> "stopped", ns::Color::red -> "red" +"running" -> 1, "blue" -> 2 +``` + +Example 2: Multiple conversions for one enumerator + +The example shows how to use multiple conversions for a single enumerator. In the example, `Color::red` will always be *serialized* to `"red"`, because the first occurring conversion. The second conversion, however, offers an alternative *deserialization* from `"rot"` to `Color::red`. + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ +enum class Color +{ + red, green, blue, unknown +}; + +NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color, +{ + { Color::unknown, "unknown" }, { Color::red, "red" }, + { Color::green, "green" }, { Color::blue, "blue" }, + { Color::red, "rot" } // a second conversion for Color::red +}) +} + +int main() +{ + // serialization + json j_red = ns::Color::red; + std::cout << static_cast(ns::Color::red) << " -> " << j_red << std::endl; + + // deserialization + json j_rot = "rot"; + auto rot = j_rot.get(); + auto red = j_red.get(); + std::cout << j_rot << " -> " << static_cast(rot) << std::endl; + std::cout << j_red << " -> " << static_cast(red) << std::endl; +} +``` + +Output: + +``` +0 -> "red" +"rot" -> 0 +"red" -> 0 +``` + +Example 3: exceptions on invalid serialization + +The example shows how an invalid serialization causes an exception to be thrown. In the example, Color::unknown is not defined in the mapping used to call `NLOHMANN_JSON_SERIALIZE_ENUM_STRICT` so causes an exception when used to serialize. Similarly, "what" does not refer to an enum value so also causes an exception when deserialization is attempted. + +``` +#include +#include + +using json = nlohmann::json; + +namespace ns +{ + +enum class Color +{ + red, + green, + blue, + unknown // not mapped in JSON_SERIALIZE_ENUM_STRICT +}; + +NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(Color, +{ + {Color::red, "red"}, + {Color::green, "green"}, + {Color::blue, "blue"} +}) + +} // namespace ns + + +int main() +{ + // invalid serialization + try + { + // ns::color::unknown was not mapped in macro + json invalid_serialization = ns::Color::unknown; + } + catch (const json::exception e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } + + // invalid deserialization + try + { + // what does not map to an enum + json invalid_deserialization("what"); + ns::Color color = invalid_deserialization.get(); + } + catch (const json::exception e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } + + return 0; +} +``` + +Output: + +``` +deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color +deserialization failed: [json.exception.out_of_range.410] enum value out of range for Color: "what" +``` + +## See also + +- [Specializing enum conversion](https://json.nlohmann.me/features/enum_conversion/index.md) +- [`NLOHMANN_JSON_SERIALIZE_ENUM`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) +- [`JSON_DISABLE_ENUM_SERIALIZATION`](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md) + +## Version history + +Added in version 3.12.x. diff --git a/api/macros/nlohmann_json_version_major.md b/api/macros/nlohmann_json_version_major.md new file mode 100644 index 000000000..d7a314276 --- /dev/null +++ b/api/macros/nlohmann_json_version_major.md @@ -0,0 +1,40 @@ +# NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH + +```cpp +#define NLOHMANN_JSON_VERSION_MAJOR /* value */ +#define NLOHMANN_JSON_VERSION_MINOR /* value */ +#define NLOHMANN_JSON_VERSION_PATCH /* value */ +``` + +These macros are defined by the library and contain the version numbers according to +[Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). + +## Default definition + +The macros are defined according to the current library version. + +## Examples + +??? example + + The example below shows how `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and + `NLOHMANN_JSON_VERSION_PATCH` are defined by the library. + + ```cpp + --8<-- "examples/nlohmann_json_version.cpp" + ``` + + Output: + + ```json + --8<-- "examples/nlohmann_json_version.output" + ``` + +## See also + +- [meta](../basic_json/meta.md) - returns version information on the library +- [JSON_SKIP_LIBRARY_VERSION_CHECK](json_skip_library_version_check.md) - skip library version check + +## Version history + +- Added in version 3.1.0. diff --git a/api/macros/nlohmann_json_version_major/index.html b/api/macros/nlohmann_json_version_major/index.html index 0ab819b40..73076de39 100644 --- a/api/macros/nlohmann_json_version_major/index.html +++ b/api/macros/nlohmann_json_version_major/index.html @@ -14,4 +14,4 @@ << NLOHMANN_JSON_VERSION_PATCH << std::endl; }

Output:

JSON for Modern C++ version 3.12.0
-

See also

Version history

  • Added in version 3.1.0.
\ No newline at end of file +

See also

Version history

  • Added in version 3.1.0.
\ No newline at end of file diff --git a/api/macros/nlohmann_json_version_major/index.md b/api/macros/nlohmann_json_version_major/index.md new file mode 100644 index 000000000..101e8534a --- /dev/null +++ b/api/macros/nlohmann_json_version_major/index.md @@ -0,0 +1,49 @@ +# NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH + +``` +#define NLOHMANN_JSON_VERSION_MAJOR /* value */ +#define NLOHMANN_JSON_VERSION_MINOR /* value */ +#define NLOHMANN_JSON_VERSION_PATCH /* value */ +``` + +These macros are defined by the library and contain the version numbers according to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). + +## Default definition + +The macros are defined according to the current library version. + +## Examples + +Example + +The example below shows how `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and `NLOHMANN_JSON_VERSION_PATCH` are defined by the library. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << "JSON for Modern C++ version " + << NLOHMANN_JSON_VERSION_MAJOR << "." + << NLOHMANN_JSON_VERSION_MINOR << "." + << NLOHMANN_JSON_VERSION_PATCH << std::endl; +} +``` + +Output: + +``` +JSON for Modern C++ version 3.12.0 +``` + +## See also + +- [meta](https://json.nlohmann.me/api/basic_json/meta/index.md) - returns version information on the library +- [JSON_SKIP_LIBRARY_VERSION_CHECK](https://json.nlohmann.me/api/macros/json_skip_library_version_check/index.md) - skip library version check + +## Version history + +- Added in version 3.1.0. diff --git a/api/operator_gtgt.md b/api/operator_gtgt.md new file mode 100644 index 000000000..6306c87f5 --- /dev/null +++ b/api/operator_gtgt.md @@ -0,0 +1,65 @@ +# nlohmann::operator>>(basic_json) + +```cpp +std::istream& operator>>(std::istream& i, basic_json& j); +``` + +Deserializes an input stream to a JSON value. + +## Parameters + +`i` (in, out) +: input stream to read a serialized JSON value from + +`j` (in, out) +: JSON value to write the deserialized input to + +## Return value + +the stream `i` + +## Exceptions + +- Throws [`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +Invalid Unicode escapes and unpaired surrogates in the input are reported as +[`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) with a detailed message. + +!!! warning "Deprecation" + + This function replaces function `#!cpp std::istream& operator<<(basic_json& j, std::istream& i)` which has + been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `#!cpp j << i;` + with `#!cpp i >> j;`. + +## Examples + +??? example + + The example below shows how a JSON value is constructed by reading a serialization from a stream. + + ```cpp + --8<-- "examples/operator_deserialize.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_deserialize.output" + ``` + +## See also + +- [accept](basic_json/accept.md) - check if the input is valid JSON +- [parse](basic_json/parse.md) - deserialize from a compatible input + +## Version history + +- Added in version 1.0.0. diff --git a/api/operator_gtgt/index.html b/api/operator_gtgt/index.html index 95fcbdc2d..e84220cbe 100644 --- a/api/operator_gtgt/index.html +++ b/api/operator_gtgt/index.html @@ -38,4 +38,4 @@ "number": 23, "string": "Hello, world!" } -

See also

  • accept - check if the input is valid JSON
  • parse - deserialize from a compatible input

Version history

  • Added in version 1.0.0.
\ No newline at end of file +

See also

  • accept - check if the input is valid JSON
  • parse - deserialize from a compatible input

Version history

  • Added in version 1.0.0.
\ No newline at end of file diff --git a/api/operator_gtgt/index.md b/api/operator_gtgt/index.md new file mode 100644 index 000000000..42eff0df3 --- /dev/null +++ b/api/operator_gtgt/index.md @@ -0,0 +1,97 @@ +# nlohmann::operator>>(basic_json) + +``` +std::istream& operator>>(std::istream& i, basic_json& j); +``` + +Deserializes an input stream to a JSON value. + +## Parameters + +`i` (in, out) : input stream to read a serialized JSON value from + +`j` (in, out) : JSON value to write the deserialized input to + +## Return value + +the stream `i` + +## Exceptions + +- Throws [`parse_error.101`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error101) in case of an unexpected token. + +## Complexity + +Linear in the length of the input. The parser is a predictive LL(1) parser. + +## Notes + +A UTF-8 byte order mark is silently ignored. + +Invalid Unicode escapes and unpaired surrogates in the input are reported as [`parse_error.101`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error101) with a detailed message. + +Deprecation + +This function replaces function `std::istream& operator<<(basic_json& j, std::istream& i)` which has been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `j << i;` with `i >> j;`. + +## Examples + +Example + +The example below shows how a JSON value is constructed by reading a serialization from a stream. + +``` +#include +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create stream with serialized JSON + std::stringstream ss; + ss << R"({ + "number": 23, + "string": "Hello, world!", + "array": [1, 2, 3, 4, 5], + "boolean": false, + "null": null + })"; + + // create JSON value and read the serialization from the stream + json j; + ss >> j; + + // serialize JSON + std::cout << std::setw(2) << j << '\n'; +} +``` + +Output: + +``` +{ + "array": [ + 1, + 2, + 3, + 4, + 5 + ], + "boolean": false, + "null": null, + "number": 23, + "string": "Hello, world!" +} +``` + +## See also + +- [accept](https://json.nlohmann.me/api/basic_json/accept/index.md) - check if the input is valid JSON +- [parse](https://json.nlohmann.me/api/basic_json/parse/index.md) - deserialize from a compatible input + +## Version history + +- Added in version 1.0.0. diff --git a/api/operator_literal_json.md b/api/operator_literal_json.md new file mode 100644 index 000000000..74cc9450c --- /dev/null +++ b/api/operator_literal_json.md @@ -0,0 +1,67 @@ +# nlohmann::operator""_json + +```cpp +json operator ""_json(const char* s, std::size_t n); +json operator ""_json(const char8_t* s, std::size_t n); // since C++20 +``` + +This operator implements a user-defined string literal for JSON objects. It can be used by adding `#!cpp _json` to a +string literal and returns a [`json`](json.md) object if no parse error occurred. + +It is recommended to bring the operator into scope using any of the following lines: +```cpp +using nlohmann::literals::operator ""_json; +using namespace nlohmann::literals; +using namespace nlohmann::json_literals; +using namespace nlohmann::literals::json_literals; +using namespace nlohmann; +``` + +This is suggested to ease migration to the next major version release of the library. See +[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. + +## Parameters + +`s` (in) +: a string representation of a JSON object + +`n` (in) +: length of string `s` + +## Return value + +[`json`](json.md) value parsed from `s` + +## Exceptions + +The function can throw anything that [`parse(s, s+n)`](basic_json/parse.md) would throw. + +## Complexity + +Linear. + +## Examples + +??? example + + The following code shows how to create JSON values from string literals. + + ```cpp + --8<-- "examples/operator_literal_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_literal_json.output" + ``` + +## See also + +- [Creating JSON values](../features/creating_values.md) - the article on creating JSON values + +## Version history + +- Added in version 1.0.0. +- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0. +- Added `char8_t*` overload in 3.12.x. diff --git a/api/operator_literal_json/index.html b/api/operator_literal_json/index.html index 24fa11e53..620c63ad2 100644 --- a/api/operator_literal_json/index.html +++ b/api/operator_literal_json/index.html @@ -22,4 +22,4 @@ "answer": 42, "hello": "world" } -

See also

Version history

  • Added in version 1.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • Added char8_t* overload in 3.12.x.
\ No newline at end of file +

See also

Version history

  • Added in version 1.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • Added char8_t* overload in 3.12.x.
\ No newline at end of file diff --git a/api/operator_literal_json/index.md b/api/operator_literal_json/index.md new file mode 100644 index 000000000..823c04bec --- /dev/null +++ b/api/operator_literal_json/index.md @@ -0,0 +1,79 @@ +# nlohmann::operator""\_json + +``` +json operator ""_json(const char* s, std::size_t n); +json operator ""_json(const char8_t* s, std::size_t n); // since C++20 +``` + +This operator implements a user-defined string literal for JSON objects. It can be used by adding `_json` to a string literal and returns a [`json`](https://json.nlohmann.me/api/json/index.md) object if no parse error occurred. + +It is recommended to bring the operator into scope using any of the following lines: + +``` +using nlohmann::literals::operator ""_json; +using namespace nlohmann::literals; +using namespace nlohmann::json_literals; +using namespace nlohmann::literals::json_literals; +using namespace nlohmann; +``` + +This is suggested to ease migration to the next major version release of the library. See [`JSON_USE_GLOBAL_UDLS`](https://json.nlohmann.me/api/macros/json_use_global_udls/#notes) for details. + +## Parameters + +`s` (in) : a string representation of a JSON object + +`n` (in) : length of string `s` + +## Return value + +[`json`](https://json.nlohmann.me/api/json/index.md) value parsed from `s` + +## Exceptions + +The function can throw anything that [`parse(s, s+n)`](https://json.nlohmann.me/api/basic_json/parse/index.md) would throw. + +## Complexity + +Linear. + +## Examples + +Example + +The following code shows how to create JSON values from string literals. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + json j = R"( {"hello": "world", "answer": 42} )"_json; + + std::cout << std::setw(2) << j << '\n'; +} +``` + +Output: + +``` +{ + "answer": 42, + "hello": "world" +} +``` + +## See also + +- [Creating JSON values](https://json.nlohmann.me/features/creating_values/index.md) - the article on creating JSON values + +## Version history + +- Added in version 1.0.0. +- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0. +- Added `char8_t*` overload in 3.12.x. diff --git a/api/operator_literal_json_pointer.md b/api/operator_literal_json_pointer.md new file mode 100644 index 000000000..f027df061 --- /dev/null +++ b/api/operator_literal_json_pointer.md @@ -0,0 +1,66 @@ +# nlohmann::operator""_json_pointer + +```cpp +json_pointer operator ""_json_pointer(const char* s, std::size_t n); +json_pointer operator ""_json_pointer(const char8_t* s, std::size_t n); // since C++20 +``` + +This operator implements a user-defined string literal for JSON Pointers. It can be used by adding `#!cpp _json_pointer` +to a string literal and returns a [`json_pointer`](json_pointer/index.md) object if no parse error occurred. + +It is recommended to bring the operator into scope using any of the following lines: +```cpp +using nlohmann::literals::operator ""_json_pointer; +using namespace nlohmann::literals; +using namespace nlohmann::json_literals; +using namespace nlohmann::literals::json_literals; +using namespace nlohmann; +``` +This is suggested to ease migration to the next major version release of the library. See +[`JSON_USE_GLOBAL_UDLS`](macros/json_use_global_udls.md#notes) for details. + +## Parameters + +`s` (in) +: a string representation of a JSON Pointer + +`n` (in) +: length of string `s` + +## Return value + +[`json_pointer`](json_pointer/index.md) value parsed from `s` + +## Exceptions + +The function can throw anything that [`json_pointer::json_pointer`](json_pointer/index.md) would throw. + +## Complexity + +Linear. + +## Examples + +??? example + + The following code shows how to create JSON Pointers from string literals. + + ```cpp + --8<-- "examples/operator_literal_json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_literal_json_pointer.output" + ``` + +## See also + +- [json_pointer](json_pointer/index.md) - type to represent JSON Pointers + +## Version history + +- Added in version 2.0.0. +- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0. +- Added `char8_t*` overload in 3.12.x. diff --git a/api/operator_literal_json_pointer/index.html b/api/operator_literal_json_pointer/index.html index 1759ddeea..cc11b1d88 100644 --- a/api/operator_literal_json_pointer/index.html +++ b/api/operator_literal_json_pointer/index.html @@ -20,4 +20,4 @@ std::cout << std::setw(2) << val << '\n'; }

Output:

"world"
-

See also

Version history

  • Added in version 2.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • Added char8_t* overload in 3.12.x.
\ No newline at end of file +

See also

Version history

  • Added in version 2.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.
  • Added char8_t* overload in 3.12.x.
\ No newline at end of file diff --git a/api/operator_literal_json_pointer/index.md b/api/operator_literal_json_pointer/index.md new file mode 100644 index 000000000..297d474c0 --- /dev/null +++ b/api/operator_literal_json_pointer/index.md @@ -0,0 +1,77 @@ +# nlohmann::operator""\_json_pointer + +``` +json_pointer operator ""_json_pointer(const char* s, std::size_t n); +json_pointer operator ""_json_pointer(const char8_t* s, std::size_t n); // since C++20 +``` + +This operator implements a user-defined string literal for JSON Pointers. It can be used by adding `_json_pointer` to a string literal and returns a [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) object if no parse error occurred. + +It is recommended to bring the operator into scope using any of the following lines: + +``` +using nlohmann::literals::operator ""_json_pointer; +using namespace nlohmann::literals; +using namespace nlohmann::json_literals; +using namespace nlohmann::literals::json_literals; +using namespace nlohmann; +``` + +This is suggested to ease migration to the next major version release of the library. See [`JSON_USE_GLOBAL_UDLS`](https://json.nlohmann.me/api/macros/json_use_global_udls/#notes) for details. + +## Parameters + +`s` (in) : a string representation of a JSON Pointer + +`n` (in) : length of string `s` + +## Return value + +[`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) value parsed from `s` + +## Exceptions + +The function can throw anything that [`json_pointer::json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) would throw. + +## Complexity + +Linear. + +## Examples + +Example + +The following code shows how to create JSON Pointers from string literals. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + json j = R"( {"hello": "world", "answer": 42} )"_json; + auto val = j["/hello"_json_pointer]; + + std::cout << std::setw(2) << val << '\n'; +} +``` + +Output: + +``` +"world" +``` + +## See also + +- [json_pointer](https://json.nlohmann.me/api/json_pointer/index.md) - type to represent JSON Pointers + +## Version history + +- Added in version 2.0.0. +- Moved to namespace `nlohmann::literals::json_literals` in 3.11.0. +- Added `char8_t*` overload in 3.12.x. diff --git a/api/operator_ltlt.md b/api/operator_ltlt.md new file mode 100644 index 000000000..1f99493d9 --- /dev/null +++ b/api/operator_ltlt.md @@ -0,0 +1,93 @@ +# nlohmann::operator<<(basic_json), nlohmann::operator<<(json_pointer) + +```cpp +std::ostream& operator<<(std::ostream& o, const basic_json& j); // (1) + +std::ostream& operator<<(std::ostream& o, const json_pointer& ptr); // (2) +``` + +1. Serialize the given JSON value `j` to the output stream `o`. The JSON value will be serialized using the + [`dump`](basic_json/dump.md) member function. + - The indentation of the output can be controlled with the member variable `width` of the output stream `o`. For + instance, using the manipulator `std::setw(4)` on `o` sets the indentation level to `4` and the serialization + result is the same as calling `dump(4)`. + - The indentation character can be controlled with the member variable `fill` of the output stream `o`. + For instance, the manipulator `std::setfill('\\t')` sets indentation to use a tab character rather than the + default space character. +2. Write a string representation of the given JSON pointer `ptr` to the output stream `o`. The string representation is + obtained using the [`to_string`](json_pointer/to_string.md) member function. + +## Parameters + +`o` (in, out) +: stream to write to + +`j` (in) +: JSON value to serialize + +`ptr` (in) +: JSON pointer to write + +## Return value + +the stream `o` + +## Exceptions + +1. Throws [`type_error.316`](../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON + value is not UTF-8 encoded. Note that unlike the [`dump`](basic_json/dump.md) member functions, no `error_handler` + can be set. +2. None. + +## Complexity + +Linear. + +## Notes + +!!! warning "Deprecation" + + Function `#!cpp std::ostream& operator<<(std::ostream& o, const basic_json& j)` replaces function + `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` which has been deprecated in version 3.0.0. + It will be removed in version 4.0.0. Please replace calls like `#!cpp j >> o;` with `#!cpp o << j;`. + +## Examples + +??? example "Example: (1) serialize JSON value to stream" + + The example below shows the serialization with different parameters to `width` to adjust the indentation level. + + ```cpp + --8<-- "examples/operator_ltlt__basic_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_ltlt__basic_json.output" + ``` + +??? example "Example: (2) write JSON pointer to stream" + + The example below shows how to write a JSON pointer to a stream. + + ```cpp + --8<-- "examples/operator_ltlt__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_ltlt__json_pointer.output" + ``` + +## See also + +- [dump](basic_json/dump.md) - serialize to a JSON-formatted string +- [Serialization](../features/serialization.md) - the serialization article + +## Version history + +1. Added in version 1.0.0. Added support for indentation character and deprecated + `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` in version 3.0.0. +2. Added in version 3.11.0. diff --git a/api/operator_ltlt/index.html b/api/operator_ltlt/index.html index f45812528..d09c2ba71 100644 --- a/api/operator_ltlt/index.html +++ b/api/operator_ltlt/index.html @@ -57,4 +57,4 @@ std::cout << ptr << std::endl; }

Output:

/foo/bar/baz
-

See also

  • dump - serialize to a JSON-formatted string
  • Serialization - the serialization article

Version history

  1. Added in version 1.0.0. Added support for indentation character and deprecated std::ostream& operator>>(const basic_json& j, std::ostream& o) in version 3.0.0.
  2. Added in version 3.11.0.
\ No newline at end of file +

See also

  • dump - serialize to a JSON-formatted string
  • Serialization - the serialization article

Version history

  1. Added in version 1.0.0. Added support for indentation character and deprecated std::ostream& operator>>(const basic_json& j, std::ostream& o) in version 3.0.0.
  2. Added in version 3.11.0.
\ No newline at end of file diff --git a/api/operator_ltlt/index.md b/api/operator_ltlt/index.md new file mode 100644 index 000000000..83f433a66 --- /dev/null +++ b/api/operator_ltlt/index.md @@ -0,0 +1,131 @@ +# nlohmann::operator\<<(basic_json), nlohmann::operator\<<(json_pointer) + +``` +std::ostream& operator<<(std::ostream& o, const basic_json& j); // (1) + +std::ostream& operator<<(std::ostream& o, const json_pointer& ptr); // (2) +``` + +1. Serialize the given JSON value `j` to the output stream `o`. The JSON value will be serialized using the [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) member function. + - The indentation of the output can be controlled with the member variable `width` of the output stream `o`. For instance, using the manipulator `std::setw(4)` on `o` sets the indentation level to `4` and the serialization result is the same as calling `dump(4)`. + - The indentation character can be controlled with the member variable `fill` of the output stream `o`. For instance, the manipulator `std::setfill('\\t')` sets indentation to use a tab character rather than the default space character. +1. Write a string representation of the given JSON pointer `ptr` to the output stream `o`. The string representation is obtained using the [`to_string`](https://json.nlohmann.me/api/json_pointer/to_string/index.md) member function. + +## Parameters + +`o` (in, out) : stream to write to + +`j` (in) : JSON value to serialize + +`ptr` (in) : JSON pointer to write + +## Return value + +the stream `o` + +## Exceptions + +1. Throws [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) if a string stored inside the JSON value is not UTF-8 encoded. Note that unlike the [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) member functions, no `error_handler` can be set. +1. None. + +## Complexity + +Linear. + +## Notes + +Deprecation + +Function `std::ostream& operator<<(std::ostream& o, const basic_json& j)` replaces function `std::ostream& operator>>(const basic_json& j, std::ostream& o)` which has been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `j >> o;` with `o << j;`. + +## Examples + +Example: (1) serialize JSON value to stream + +The example below shows the serialization with different parameters to `width` to adjust the indentation level. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + + // serialize without indentation + std::cout << j_object << "\n\n"; + std::cout << j_array << "\n\n"; + + // serialize with indentation + std::cout << std::setw(4) << j_object << "\n\n"; + std::cout << std::setw(2) << j_array << "\n\n"; + std::cout << std::setw(1) << std::setfill('\t') << j_object << "\n\n"; +} +``` + +Output: + +``` +{"one":1,"two":2} + +[1,2,4,8,16] + +{ + "one": 1, + "two": 2 +} + +[ + 1, + 2, + 4, + 8, + 16 +] + +{ + "one": 1, + "two": 2 +} +``` + +Example: (2) write JSON pointer to stream + +The example below shows how to write a JSON pointer to a stream. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON pointer + json::json_pointer ptr("/foo/bar/baz"); + + // write string representation to stream + std::cout << ptr << std::endl; +} +``` + +Output: + +``` +/foo/bar/baz +``` + +## See also + +- [dump](https://json.nlohmann.me/api/basic_json/dump/index.md) - serialize to a JSON-formatted string +- [Serialization](https://json.nlohmann.me/features/serialization/index.md) - the serialization article + +## Version history + +1. Added in version 1.0.0. Added support for indentation character and deprecated `std::ostream& operator>>(const basic_json& j, std::ostream& o)` in version 3.0.0. +1. Added in version 3.11.0. diff --git a/api/ordered_json.md b/api/ordered_json.md new file mode 100644 index 000000000..b28fe36f6 --- /dev/null +++ b/api/ordered_json.md @@ -0,0 +1,39 @@ +# nlohmann::ordered_json + +```cpp +using ordered_json = basic_json; +``` + +This type preserves the insertion order of object keys. + +## Iterator invalidation + +The type is based on [`ordered_map`](ordered_map.md) which in turn uses a `std::vector` to store object elements. +Therefore, adding object elements can yield a reallocation in which case all iterators (including the +[`end()`](basic_json/end.md) iterator) and all references to the elements are invalidated. Also, any iterator or +reference after the insertion point will point to the same index, which is now a different value. + +## Examples + +??? example + + The example below demonstrates how `ordered_json` preserves the insertion order of object keys. + + ```cpp + --8<-- "examples/ordered_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_json.output" + ``` + +## See also + +- [ordered_map](ordered_map.md) +- [Object Order](../features/object_order.md) + +## Version history + +Since version 3.9.0. diff --git a/api/ordered_json/index.html b/api/ordered_json/index.html index 0e31914dd..bdae9a677 100644 --- a/api/ordered_json/index.html +++ b/api/ordered_json/index.html @@ -18,4 +18,4 @@ "two": 2, "three": 3 } -

See also

Version history

Since version 3.9.0.

\ No newline at end of file +

See also

Version history

Since version 3.9.0.

\ No newline at end of file diff --git a/api/ordered_json/index.md b/api/ordered_json/index.md new file mode 100644 index 000000000..3c9d5975a --- /dev/null +++ b/api/ordered_json/index.md @@ -0,0 +1,53 @@ +# nlohmann::ordered_json + +``` +using ordered_json = basic_json; +``` + +This type preserves the insertion order of object keys. + +## Iterator invalidation + +The type is based on [`ordered_map`](https://json.nlohmann.me/api/ordered_map/index.md) which in turn uses a `std::vector` to store object elements. Therefore, adding object elements can yield a reallocation in which case all iterators (including the [`end()`](https://json.nlohmann.me/api/basic_json/end/index.md) iterator) and all references to the elements are invalidated. Also, any iterator or reference after the insertion point will point to the same index, which is now a different value. + +## Examples + +Example + +The example below demonstrates how `ordered_json` preserves the insertion order of object keys. + +``` +#include +#include + +using ordered_json = nlohmann::ordered_json; + +int main() +{ + ordered_json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + std::cout << j.dump(2) << '\n'; +} +``` + +Output: + +``` +{ + "one": 1, + "two": 2, + "three": 3 +} +``` + +## See also + +- [ordered_map](https://json.nlohmann.me/api/ordered_map/index.md) +- [Object Order](https://json.nlohmann.me/features/object_order/index.md) + +## Version history + +Since version 3.9.0. diff --git a/api/ordered_map.md b/api/ordered_map.md new file mode 100644 index 000000000..ca4934161 --- /dev/null +++ b/api/ordered_map.md @@ -0,0 +1,82 @@ +# nlohmann::ordered_map + +```cpp +template, + class Allocator = std::allocator>> +struct ordered_map : std::vector, Allocator>; +``` + +A minimal map-like container that preserves insertion order for use within [`nlohmann::ordered_json`](ordered_json.md) +(`nlohmann::basic_json`). + +## Template parameters + +`Key` +: key type + +`T` +: mapped type + +`IgnoredLess` +: comparison function (ignored and only added to ensure compatibility with `#!cpp std::map`) + +`Allocator` +: allocator type + +## Iterator invalidation + +The type uses a `std::vector` to store object elements. Therefore, adding elements can yield a reallocation in which +case all iterators (including the `end()` iterator) and all references to the elements are invalidated. + +## Member types + +- **key_type** - key type (`Key`) +- **mapped_type** - mapped type (`T`) +- **Container** - base container type (`#!cpp std::vector, Allocator>`) +- **iterator** +- **const_iterator** +- **size_type** +- **value_type** +- **key_compare** - key comparison function +```cpp +std::equal_to // until C++14 + +std::equal_to<> // since C++14 +``` + +## Member functions + +- (constructor) +- (destructor) +- **emplace** +- **operator\[\]** +- **at** +- **erase** +- **count** +- **find** +- **insert** + +## Examples + +??? example + + The example shows the different behavior of `std::map` and `nlohmann::ordered_map`. + + ```cpp + --8<-- "examples/ordered_map.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_map.output" + ``` + +## See also + +- [ordered_json](ordered_json.md) + +## Version history + +- Added in version 3.9.0 to implement [`nlohmann::ordered_json`](ordered_json.md). +- Added **key_compare** member in version 3.11.0. diff --git a/api/ordered_map/index.html b/api/ordered_map/index.html index 3ff3b6601..3047bed38 100644 --- a/api/ordered_map/index.html +++ b/api/ordered_map/index.html @@ -51,4 +51,4 @@ m_std = { one:eins three:drei two:zwei } m_ordered = { two:zwei three:drei one:eins } m_std = { one:eins three:drei two:zwei } -

See also

Version history

\ No newline at end of file +

See also

Version history

\ No newline at end of file diff --git a/api/ordered_map/index.md b/api/ordered_map/index.md new file mode 100644 index 000000000..1d9db4b19 --- /dev/null +++ b/api/ordered_map/index.md @@ -0,0 +1,129 @@ +# nlohmann::ordered_map + +``` +template, + class Allocator = std::allocator>> +struct ordered_map : std::vector, Allocator>; +``` + +A minimal map-like container that preserves insertion order for use within [`nlohmann::ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) (`nlohmann::basic_json`). + +## Template parameters + +`Key` : key type + +`T` : mapped type + +`IgnoredLess` : comparison function (ignored and only added to ensure compatibility with `std::map`) + +`Allocator` : allocator type + +## Iterator invalidation + +The type uses a `std::vector` to store object elements. Therefore, adding elements can yield a reallocation in which case all iterators (including the `end()` iterator) and all references to the elements are invalidated. + +## Member types + +- **key_type** - key type (`Key`) + +- **mapped_type** - mapped type (`T`) + +- **Container** - base container type (`std::vector, Allocator>`) + +- **iterator** + +- **const_iterator** + +- **size_type** + +- **value_type** + +- **key_compare** - key comparison function + + ``` + std::equal_to // until C++14 + + std::equal_to<> // since C++14 + ``` + +## Member functions + +- (constructor) +- (destructor) +- **emplace** +- **operator[]** +- **at** +- **erase** +- **count** +- **find** +- **insert** + +## Examples + +Example + +The example shows the different behavior of `std::map` and `nlohmann::ordered_map`. + +``` +#include +#include + +// simple output function +template +void output(const char* prefix, const Map& m) +{ + std::cout << prefix << " = { "; + for (auto& element : m) + { + std::cout << element.first << ":" << element.second << ' '; + } + std::cout << "}" << std::endl; +} + +int main() +{ + // create and fill two maps + nlohmann::ordered_map m_ordered; + m_ordered["one"] = "eins"; + m_ordered["two"] = "zwei"; + m_ordered["three"] = "drei"; + + std::map m_std; + m_std["one"] = "eins"; + m_std["two"] = "zwei"; + m_std["three"] = "drei"; + + // output: m_ordered is ordered by insertion order, m_std is ordered by key + output("m_ordered", m_ordered); + output("m_std", m_std); + + // erase and re-add "one" key + m_ordered.erase("one"); + m_ordered["one"] = "eins"; + + m_std.erase("one"); + m_std["one"] = "eins"; + + // output: m_ordered shows newly added key at the end; m_std is again ordered by key + output("m_ordered", m_ordered); + output("m_std", m_std); +} +``` + +Output: + +``` +m_ordered = { one:eins two:zwei three:drei } +m_std = { one:eins three:drei two:zwei } +m_ordered = { two:zwei three:drei one:eins } +m_std = { one:eins three:drei two:zwei } +``` + +## See also + +- [ordered_json](https://json.nlohmann.me/api/ordered_json/index.md) + +## Version history + +- Added in version 3.9.0 to implement [`nlohmann::ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md). +- Added **key_compare** member in version 3.11.0. diff --git a/assets/external/repology.org/badge/vertical-allrepos/nlohmann-json.svg b/assets/external/repology.org/badge/vertical-allrepos/nlohmann-json.svg index a65ab94a2..64f52ba64 100644 --- a/assets/external/repology.org/badge/vertical-allrepos/nlohmann-json.svg +++ b/assets/external/repology.org/badge/vertical-allrepos/nlohmann-json.svg @@ -1 +1 @@ -Packaging statusPackaging statusAdélie Linux currentAdélie Linux current3.11.33.11.3Alpine Linux 3.17Alpine Linux 3.173.11.23.11.2Alpine Linux 3.18Alpine Linux 3.183.11.23.11.2Alpine Linux 3.19Alpine Linux 3.193.11.33.11.3Alpine Linux 3.20Alpine Linux 3.203.11.33.11.3Alpine Linux 3.21Alpine Linux 3.213.11.33.11.3Alpine Linux 3.22Alpine Linux 3.223.11.33.11.3Alpine Linux 3.23Alpine Linux 3.233.11.33.11.3Alpine Linux 3.24Alpine Linux 3.243.11.33.11.3Alpine Linux EdgeAlpine Linux Edge3.11.33.11.3ALT Linux p11ALT Linux p113.11.33.11.3ALT SisyphusALT Sisyphus3.12.03.12.0AOSCAOSC3.12.03.12.0Apertis v2023Apertis v20233.9.13.9.1Apertis v2024Apertis v20243.11.23.11.2Apertis v2025Apertis v20253.11.23.11.2Apertis v2026Apertis v20263.11.33.11.3Apertis v2027 DevelopmentApertis v2027 Development3.11.33.11.3Arch LinuxArch Linux3.12.03.12.0ArchPOWER powerpcArchPOWER powerpc3.12.03.12.0ArchPOWER powerpc64leArchPOWER powerpc64le3.12.03.12.0ArchPOWER riscv64ArchPOWER riscv643.12.03.12.0AURAUR3.12.03.12.0ArtixArtix3.12.03.12.0Chimera LinuxChimera Linux3.12.03.12.0ConanCenterConanCenter3.12.03.12.0CRUX 3.7CRUX 3.73.12.03.12.0CRUX 3.8CRUX 3.83.12.03.12.0Debian 11Debian 113.9.13.9.1Debian 12Debian 123.11.23.11.2Debian 13Debian 133.11.33.11.3Debian 14Debian 143.12.0.reall…3.12.0.reall…Debian UnstableDebian Unstable3.12.0.reall…3.12.0.reall…Debian ExperimentalDebian Experimental3.12.0.reall…3.12.0.reall…deepin 20deepin 203.9.13.9.1deepin 23deepin 233.11.33.11.3Devuan 4.0Devuan 4.03.9.13.9.1Devuan UnstableDevuan Unstable3.12.0.reall…3.12.0.reall…EPEL 7EPEL 73.6.13.6.1EPEL 8EPEL 83.6.13.6.1EPEL 9EPEL 93.11.33.11.3EPEL 10EPEL 103.11.33.11.3ExherboExherbo3.12.03.12.0Fedora 39Fedora 393.11.23.11.2Fedora 40Fedora 403.11.33.11.3Fedora 41Fedora 413.11.33.11.3Fedora 42Fedora 423.11.33.11.3Fedora 43Fedora 433.11.33.11.3Fedora 44Fedora 443.12.03.12.0Fedora RawhideFedora Rawhide3.12.03.12.0FreeBSD PortsFreeBSD Ports3.12.03.12.0GentooGentoo3.12.03.12.0GNU GuixGNU Guix3.12.03.12.0HaikuPorts masterHaikuPorts master3.12.03.12.0HomebrewHomebrew3.12.03.12.0Kali Linux RollingKali Linux Rolling3.12.0.reall…3.12.0.reall…KaOSKaOS3.12.03.12.0LiGurOS stableLiGurOS stable3.12.03.12.0LiGurOS developLiGurOS develop3.12.03.12.0MacPortsMacPorts3.12.03.12.0Mageia 9Mageia 93.11.23.11.2Mageia cauldronMageia cauldron3.12.03.12.0Manjaro StableManjaro Stable3.12.03.12.0Manjaro TestingManjaro Testing3.12.03.12.0Manjaro UnstableManjaro Unstable3.12.03.12.0MSYS2 clang64MSYS2 clang643.12.03.12.0MSYS2 clangarm64MSYS2 clangarm643.12.03.12.0MSYS2 mingwMSYS2 mingw3.12.03.12.0MSYS2 ucrt64MSYS2 ucrt643.12.03.12.0nixpkgs stable 23.11nixpkgs stable 23.113.11.23.11.2nixpkgs stable 24.05nixpkgs stable 24.053.11.33.11.3nixpkgs stable 24.11nixpkgs stable 24.113.11.33.11.3nixpkgs stable 25.05nixpkgs stable 25.053.11.33.11.3nixpkgs stable 25.11nixpkgs stable 25.113.12.03.12.0nixpkgs stable 26.05nixpkgs stable 26.053.12.03.12.0nixpkgs unstablenixpkgs unstable3.12.03.12.0OpenBSD PortsOpenBSD Ports3.12.03.12.0OpenIndiana packagesOpenIndiana packages3.12.03.12.0openmambaopenmamba3.12.03.12.0OpenMandriva 6.0OpenMandriva 6.03.12.03.12.0OpenMandriva RollingOpenMandriva Rolling3.12.03.12.0OpenMandriva CookerOpenMandriva Cooker3.12.03.12.0openSUSE Leap 15.5openSUSE Leap 15.53.11.23.11.2openSUSE Leap 15.6openSUSE Leap 15.63.11.23.11.2openSUSE TumbleweedopenSUSE Tumbleweed3.12.03.12.0openSUSE hardware:sdr TumbleweedopenSUSE hardware:sdr Tumbleweed3.12.03.12.0PackMan SLE 12PackMan SLE 123.1.23.1.2ParabolaParabola3.12.03.12.0Pardus 21Pardus 213.9.13.9.1ParrotParrot3.11.33.11.3Pisi LinuxPisi Linux3.11.23.11.2pkgsrc-2025Q4pkgsrc-2025Q43.12.03.12.0pkgsrc-2026Q1pkgsrc-2026Q13.12.03.12.0pkgsrc currentpkgsrc current3.12.03.12.0PLD LinuxPLD Linux3.11.33.11.3PTXdistPTXdist3.12.03.12.0PureOS amberPureOS amber3.5.03.5.0PureOS byzantiumPureOS byzantium3.9.13.9.1PureOS landingPureOS landing3.11.33.11.3Raspbian OldstableRaspbian Oldstable3.11.23.11.2Raspbian StableRaspbian Stable3.11.33.11.3Raspbian TestingRaspbian Testing3.12.0.reall…3.12.0.reall…RavenportsRavenports3.12.03.12.0Rosa 2021.1Rosa 2021.13.11.33.11.3Rosa 13Rosa 133.11.33.11.3SlackBuildsSlackBuilds3.11.33.11.3Slackware currentSlackware current3.12.03.12.0Slackware64 currentSlackware64 current3.12.03.12.0SolusSolus3.11.33.11.3SpackSpack3.12.03.12.0stal/IXstal/IX3.12.03.12.0stal/IX devstal/IX dev3.12.03.12.0T2 SDET2 SDE3.12.03.12.0TermuxTermux3.12.03.12.0Trisquel 10.0Trisquel 10.03.7.33.7.3Trisquel 11.0Trisquel 11.03.10.53.10.5Ubuntu 18.04Ubuntu 18.042.1.12.1.1Ubuntu 20.04Ubuntu 20.043.7.33.7.3Ubuntu 22.04Ubuntu 22.043.10.53.10.5Ubuntu 24.04Ubuntu 24.043.11.33.11.3Ubuntu 25.04Ubuntu 25.043.11.33.11.3Ubuntu 25.10Ubuntu 25.103.12.03.12.0Ubuntu 26.04Ubuntu 26.043.12.0.reall…3.12.0.reall…Ubuntu 26.10Ubuntu 26.103.12.0.reall…3.12.0.reall…VcpkgVcpkg3.12.03.12.0Void Linux x86_64Void Linux x86_643.12.03.12.0YACPYACP3.12.03.12.0 \ No newline at end of file +Packaging statusPackaging statusAdélie Linux currentAdélie Linux current3.11.33.11.3Alpine Linux 3.17Alpine Linux 3.173.11.23.11.2Alpine Linux 3.18Alpine Linux 3.183.11.23.11.2Alpine Linux 3.19Alpine Linux 3.193.11.33.11.3Alpine Linux 3.20Alpine Linux 3.203.11.33.11.3Alpine Linux 3.21Alpine Linux 3.213.11.33.11.3Alpine Linux 3.22Alpine Linux 3.223.11.33.11.3Alpine Linux 3.23Alpine Linux 3.233.11.33.11.3Alpine Linux 3.24Alpine Linux 3.243.11.33.11.3Alpine Linux EdgeAlpine Linux Edge3.11.33.11.3ALT Linux p11ALT Linux p113.11.33.11.3ALT SisyphusALT Sisyphus3.12.03.12.0AOSCAOSC3.12.03.12.0Apertis v2023Apertis v20233.9.13.9.1Apertis v2024Apertis v20243.11.23.11.2Apertis v2025Apertis v20253.11.23.11.2Apertis v2026Apertis v20263.11.33.11.3Apertis v2027 DevelopmentApertis v2027 Development3.11.33.11.3Arch LinuxArch Linux3.12.03.12.0ArchPOWER powerpcArchPOWER powerpc3.12.03.12.0ArchPOWER powerpc64leArchPOWER powerpc64le3.12.03.12.0ArchPOWER riscv64ArchPOWER riscv643.12.03.12.0AURAUR3.12.03.12.0ArtixArtix3.12.03.12.0Chimera LinuxChimera Linux3.12.03.12.0ConanCenterConanCenter3.12.03.12.0CRUX 3.7CRUX 3.73.12.03.12.0CRUX 3.8CRUX 3.83.12.03.12.0Debian 11Debian 113.9.13.9.1Debian 12Debian 123.11.23.11.2Debian 13Debian 133.11.33.11.3Debian 14Debian 143.12.0.reall…3.12.0.reall…Debian UnstableDebian Unstable3.12.0.reall…3.12.0.reall…Debian ExperimentalDebian Experimental3.12.0.reall…3.12.0.reall…deepin 20deepin 203.9.13.9.1deepin 23deepin 233.11.33.11.3Devuan 4.0Devuan 4.03.9.13.9.1Devuan UnstableDevuan Unstable3.12.0.reall…3.12.0.reall…EPEL 7EPEL 73.6.13.6.1EPEL 8EPEL 83.6.13.6.1EPEL 9EPEL 93.11.33.11.3EPEL 10EPEL 103.11.33.11.3ExherboExherbo3.12.03.12.0Fedora 39Fedora 393.11.23.11.2Fedora 40Fedora 403.11.33.11.3Fedora 41Fedora 413.11.33.11.3Fedora 42Fedora 423.11.33.11.3Fedora 43Fedora 433.11.33.11.3Fedora 44Fedora 443.12.03.12.0Fedora RawhideFedora Rawhide3.12.03.12.0FreeBSD PortsFreeBSD Ports3.12.03.12.0GentooGentoo3.12.03.12.0GNU GuixGNU Guix3.12.03.12.0HaikuPorts masterHaikuPorts master3.12.03.12.0HomebrewHomebrew3.12.03.12.0Kali Linux RollingKali Linux Rolling3.12.0.reall…3.12.0.reall…KaOSKaOS3.12.03.12.0LiGurOS stableLiGurOS stable3.12.03.12.0LiGurOS developLiGurOS develop3.12.03.12.0MacPortsMacPorts3.12.03.12.0Mageia 9Mageia 93.11.23.11.2Mageia cauldronMageia cauldron3.12.03.12.0Manjaro StableManjaro Stable3.12.03.12.0Manjaro TestingManjaro Testing3.12.03.12.0Manjaro UnstableManjaro Unstable3.12.03.12.0MSYS2 clang64MSYS2 clang643.12.03.12.0MSYS2 clangarm64MSYS2 clangarm643.12.03.12.0MSYS2 mingwMSYS2 mingw3.12.03.12.0MSYS2 ucrt64MSYS2 ucrt643.12.03.12.0nixpkgs stable 23.11nixpkgs stable 23.113.11.23.11.2nixpkgs stable 24.05nixpkgs stable 24.053.11.33.11.3nixpkgs stable 24.11nixpkgs stable 24.113.11.33.11.3nixpkgs stable 25.05nixpkgs stable 25.053.11.33.11.3nixpkgs stable 25.11nixpkgs stable 25.113.12.03.12.0nixpkgs stable 26.05nixpkgs stable 26.053.12.03.12.0nixpkgs unstablenixpkgs unstable3.12.03.12.0OpenBSD PortsOpenBSD Ports3.12.03.12.0OpenIndiana packagesOpenIndiana packages3.12.03.12.0openmambaopenmamba3.12.03.12.0OpenMandriva 6.0OpenMandriva 6.03.12.03.12.0OpenMandriva RollingOpenMandriva Rolling3.12.03.12.0OpenMandriva CookerOpenMandriva Cooker3.12.03.12.0openSUSE Leap 15.5openSUSE Leap 15.53.11.23.11.2openSUSE Leap 15.6openSUSE Leap 15.63.11.23.11.2openSUSE TumbleweedopenSUSE Tumbleweed3.12.03.12.0openSUSE hardware:sdr TumbleweedopenSUSE hardware:sdr Tumbleweed3.12.03.12.0PackMan SLE 12PackMan SLE 123.1.23.1.2ParabolaParabola3.12.03.12.0Pardus 21Pardus 213.9.13.9.1ParrotParrot3.11.33.11.3Pisi LinuxPisi Linux3.11.23.11.2pkgsrc-2025Q4pkgsrc-2025Q43.12.03.12.0pkgsrc-2026Q1pkgsrc-2026Q13.12.03.12.0pkgsrc currentpkgsrc current3.12.03.12.0PLD LinuxPLD Linux3.11.33.11.3PTXdistPTXdist3.12.03.12.0PureOS amberPureOS amber3.5.03.5.0PureOS byzantiumPureOS byzantium3.9.13.9.1PureOS landingPureOS landing3.11.33.11.3Raspbian OldstableRaspbian Oldstable3.11.23.11.2Raspbian StableRaspbian Stable3.11.33.11.3Raspbian TestingRaspbian Testing3.12.0.reall…3.12.0.reall…RavenportsRavenports3.12.03.12.0Rosa 2021.1Rosa 2021.13.11.33.11.3Rosa 13Rosa 133.11.33.11.3SlackBuildsSlackBuilds3.11.33.11.3Slackware currentSlackware current3.12.03.12.0Slackware64 currentSlackware64 current3.12.03.12.0SolusSolus3.12.03.12.0SpackSpack3.12.03.12.0stal/IXstal/IX3.12.03.12.0stal/IX devstal/IX dev3.12.03.12.0T2 SDET2 SDE3.12.03.12.0TermuxTermux3.12.03.12.0Trisquel 10.0Trisquel 10.03.7.33.7.3Trisquel 11.0Trisquel 11.03.10.53.10.5Ubuntu 18.04Ubuntu 18.042.1.12.1.1Ubuntu 20.04Ubuntu 20.043.7.33.7.3Ubuntu 22.04Ubuntu 22.043.10.53.10.5Ubuntu 24.04Ubuntu 24.043.11.33.11.3Ubuntu 25.04Ubuntu 25.043.11.33.11.3Ubuntu 25.10Ubuntu 25.103.12.03.12.0Ubuntu 26.04Ubuntu 26.043.12.0.reall…3.12.0.reall…Ubuntu 26.10Ubuntu 26.103.12.0.reall…3.12.0.reall…VcpkgVcpkg3.12.03.12.0Void Linux x86_64Void Linux x86_643.12.03.12.0YACPYACP3.12.03.12.0 \ No newline at end of file diff --git a/community.md b/community.md new file mode 100644 index 000000000..caef17be3 --- /dev/null +++ b/community.md @@ -0,0 +1,7 @@ +# Community + +- [Code of Conduct](code_of_conduct.md) - the rules and norms of this project +- [Contribution Guidelines](contribution_guidelines.md) - guidelines how to contribute to this project +- [Governance](governance.md) - the governance model of this project +- [Quality Assurance](quality_assurance.md) - how the quality of this project is assured +- [Security Policy](security_policy.md) - the security policy of the project diff --git a/community/code_of_conduct.md b/community/code_of_conduct.md new file mode 100644 index 000000000..0685e0e57 --- /dev/null +++ b/community/code_of_conduct.md @@ -0,0 +1 @@ +--8<-- "../../../.github/CODE_OF_CONDUCT.md" diff --git a/community/code_of_conduct/index.html b/community/code_of_conduct/index.html index d70a971bf..411a2b289 100644 --- a/community/code_of_conduct/index.html +++ b/community/code_of_conduct/index.html @@ -1 +1 @@ - Code of Conduct - JSON for Modern C++

Contributor Covenant Code of Conduct

Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

Our Standards

Examples of behavior that contributes to a positive environment for our community include:

  • Demonstrating empathy and kindness toward other people
  • Being respectful of differing opinions, viewpoints, and experiences
  • Giving and gracefully accepting constructive feedback
  • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
  • Focusing on what is best not just for us as individuals, but for the overall community

Examples of unacceptable behavior include:

  • The use of sexualized language or imagery, and sexual attention or advances of any kind
  • Trolling, insulting or derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or email address, without their explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting

Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

Scope

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at mail@nlohmann.me. All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the reporter of any incident.

Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

1. Correction

Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

2. Warning

Community Impact: A violation through a single incident or series of actions.

Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

3. Temporary Ban

Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

4. Permanent Ban

Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

Consequence: A permanent ban from any sort of public interaction within the community.

Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

\ No newline at end of file + Code of Conduct - JSON for Modern C++

Contributor Covenant Code of Conduct

Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

Our Standards

Examples of behavior that contributes to a positive environment for our community include:

  • Demonstrating empathy and kindness toward other people
  • Being respectful of differing opinions, viewpoints, and experiences
  • Giving and gracefully accepting constructive feedback
  • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
  • Focusing on what is best not just for us as individuals, but for the overall community

Examples of unacceptable behavior include:

  • The use of sexualized language or imagery, and sexual attention or advances of any kind
  • Trolling, insulting or derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or email address, without their explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting

Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

Scope

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at mail@nlohmann.me. All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the reporter of any incident.

Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

1. Correction

Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

2. Warning

Community Impact: A violation through a single incident or series of actions.

Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

3. Temporary Ban

Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

4. Permanent Ban

Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

Consequence: A permanent ban from any sort of public interaction within the community.

Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

\ No newline at end of file diff --git a/community/code_of_conduct/index.md b/community/code_of_conduct/index.md new file mode 100644 index 000000000..396fb5ef9 --- /dev/null +++ b/community/code_of_conduct/index.md @@ -0,0 +1,77 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [mail@nlohmann.me](mailto:mail@nlohmann.me). All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1, available at . + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). + +For answers to common questions about this code of conduct, see the FAQ at . Translations are available at . diff --git a/community/contribution_guidelines.md b/community/contribution_guidelines.md new file mode 100644 index 000000000..d439f1cfb --- /dev/null +++ b/community/contribution_guidelines.md @@ -0,0 +1 @@ +--8<-- "../../../.github/CONTRIBUTING.md" diff --git a/community/contribution_guidelines/index.html b/community/contribution_guidelines/index.html index eb9e86cc4..a116772c3 100644 --- a/community/contribution_guidelines/index.html +++ b/community/contribution_guidelines/index.html @@ -5,4 +5,4 @@ $ ctest --test-dir

Add tests

The tests are located in tests/src/unit-*.cpp and contain doctest assertions like CHECK. The tests are structured along the features of the library or the nature of the tests. Usually, it should be clear from the context which existing file needs to be extended, and only very few cases require creating new test files.

When fixing a bug, edit unit-regression2.cpp and add a section referencing the fixed issue.

Exceptions

When you test exceptions, please use CHECK_THROWS_WITH_AS which also takes the what() argument of the thrown exception into account.

Coverage

If test coverage decreases, an automatic warning comment will be posted on the pull request. You can access a code coverage report as an artifact to the “Ubuntu” workflow.

Update the documentation

The main documentation of the library is generated from the files docs/mkdocs/docs. This folder contains dedicated pages for certain features, a list of all exceptions, and extensive API documentation with details on every public API function.

Build the documentation locally using:

make install_venv -C docs/mkdocs
 make serve -C docs/mkdocs
 

The documentation will then be available at http://127.0.0.1:8000/. See the documentation of mkdocs and Material for MkDocs for more information.

Amalgamate the source code

The single-header files single_include/nlohmann/json.hpp and single_include/nlohmann/json_fwd.hpp are generated from the source files in the include/nlohmann directory. Do not edit the files directly; instead, modify the include/nlohmann sources and regenerate the files by executing:

make amalgamate
-

Running make amalgamate will also apply automatic formatting to the source files using Artistic Style. This formatting may modify your source files in-place. Be certain to review and commit any changes to avoid unintended formatting diffs in commits.

  • The library’s README file is an excellent starting point to understand its functionality.
  • The documentation page is the reference documentation of the library.
  • RFC 8259 is the reference for the JavaScript Object Notation (JSON) Data Interchange Format.

Please don't...

Certain contributions are not helpful.

Break the public API

We take pride in the library being used by numerous customers across various industries. They all rely on the guarantees provided by semantic versioning. Please do not change the library such that the public API of the 3.x.y version is broken. This includes:

  • Changing function signatures (altering parameter types, return types, number of parameters) or changing the const-ness of member functions.
  • Removing functions.
  • Renaming functions or classes.
  • Changing exception handling.
  • Changing exception ids.
  • Changing access specifiers.
  • Changing default arguments.

Although these guidelines may seem restrictive, they are essential for maintaining the library’s utility.

Breaking changes may be introduced when they are guarded with a feature macro such as JSON_USE_IMPLICIT_CONVERSIONS which allows selectively changing the behavior of the library. In next steps, the current behavior can then be deprecated. Using feature macros then allows users to test their code against the library in the next major release.

Break C++11 language conformance

This library is designed to work with C++11 and later. This means that any supported C++11 compiler should compile the library without problems. Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support.

Please do not add features that do not work with the mentioned supported compilers. Please guard features from C++14 and later against the respective JSON_HAS_CPP_14 macros.

Break JSON conformance

Please refrain from proposing changes that would break JSON conformance. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.

Wanted

The following areas really need contribution and are always welcomed:

  • Extending the continuous integration toward more exotic compilers such as Android NDK, Intel's Compiler, or the bleeding-edge versions Clang.
  • Improving the efficiency of the JSON parser. The current parser is implemented as a naive recursive descent parser with hand-coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the json.hpp header, and I am not aware of approaches similar to re2c for parsing.
  • Extending and updating existing benchmarks to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting.

We look forward to your contributions and collaboration to enhance the library!

\ No newline at end of file +

Running make amalgamate will also apply automatic formatting to the source files using Artistic Style. This formatting may modify your source files in-place. Be certain to review and commit any changes to avoid unintended formatting diffs in commits.

  • The library’s README file is an excellent starting point to understand its functionality.
  • The documentation page is the reference documentation of the library.
  • RFC 8259 is the reference for the JavaScript Object Notation (JSON) Data Interchange Format.

Please don't...

Certain contributions are not helpful.

Break the public API

We take pride in the library being used by numerous customers across various industries. They all rely on the guarantees provided by semantic versioning. Please do not change the library such that the public API of the 3.x.y version is broken. This includes:

  • Changing function signatures (altering parameter types, return types, number of parameters) or changing the const-ness of member functions.
  • Removing functions.
  • Renaming functions or classes.
  • Changing exception handling.
  • Changing exception ids.
  • Changing access specifiers.
  • Changing default arguments.

Although these guidelines may seem restrictive, they are essential for maintaining the library’s utility.

Breaking changes may be introduced when they are guarded with a feature macro such as JSON_USE_IMPLICIT_CONVERSIONS which allows selectively changing the behavior of the library. In next steps, the current behavior can then be deprecated. Using feature macros then allows users to test their code against the library in the next major release.

Break C++11 language conformance

This library is designed to work with C++11 and later. This means that any supported C++11 compiler should compile the library without problems. Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support.

Please do not add features that do not work with the mentioned supported compilers. Please guard features from C++14 and later against the respective JSON_HAS_CPP_14 macros.

Break JSON conformance

Please refrain from proposing changes that would break JSON conformance. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension.

Wanted

The following areas really need contribution and are always welcomed:

  • Extending the continuous integration toward more exotic compilers such as Android NDK, Intel's Compiler, or the bleeding-edge versions Clang.
  • Improving the efficiency of the JSON parser. The current parser is implemented as a naive recursive descent parser with hand-coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the json.hpp header, and I am not aware of approaches similar to re2c for parsing.
  • Extending and updating existing benchmarks to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting.

We look forward to your contributions and collaboration to enhance the library!

\ No newline at end of file diff --git a/community/contribution_guidelines/index.md b/community/contribution_guidelines/index.md new file mode 100644 index 000000000..f5ec47211 --- /dev/null +++ b/community/contribution_guidelines/index.md @@ -0,0 +1,160 @@ +# Contribution Guidelines + +Thank you for your interest in contributing to this project! What began as an exercise to explore the exciting features of C++11 has evolved into a [widely used](https://json.nlohmann.me/home/customers/) JSON library. I truly appreciate all the contributions from the community, whether it's proposing features, identifying bugs, or fixing mistakes! To ensure that our collaboration is efficient and effective, please follow these guidelines. + +Feel free to discuss or suggest improvements to this document [by submitting a pull request](https://github.com/nlohmann/json/edit/develop/.github/CONTRIBUTING.md). + +## Ways to Contribute + +There are multiple ways to contribute. + +### Reporting an issue + +Please [create an issue](https://github.com/nlohmann/json/issues/new/choose), assuming one does not already exist, and describe your concern. Note you need a [GitHub account](https://github.com/signup/free) for this. + +Clearly describe the issue: + +- If it is a bug, please describe how to **reproduce** it. If possible, attach a *complete example* which demonstrates the error. Please also state what you **expected** to happen instead of the error. +- If you propose a change or addition, try to give an **example** what the improved code could look like or how to use it. +- If you found a compilation error, please tell us which **compiler** (version and operating system) you used and paste the (relevant part of) the error messages to the ticket. + +Please stick to the provided issue template [bug report](https://github.com/nlohmann/json/blob/develop/.github/ISSUE_TEMPLATE/bug.yaml) if possible. + +### Reporting a security vulnerability + +You can report a security vulnerability according to our [security policy](https://github.com/nlohmann/json/security/policy). + +### Discussing a new feature + +For questions, feature or support requests, please [open a discussion](https://github.com/nlohmann/json/discussions/new). If you find a proposed answer satisfactory, please use the "Mark as answer" button to make it easier for readers to see what helped and for the community to filter for open questions. + +### Proposing a fix or an improvement + +Join an ongoing discussion or comment on an existing issue before starting to code. This can help to avoid duplicate efforts or other frustration during the later review. + +Create a [pull request](https://github.com/nlohmann/json/pulls?q=sort%3Aupdated-desc+is%3Apr+is%3Aopen) against the `develop` branch and follow the pull request template. In particular, + +- describe the changes in detail, both the what and why, +- reference existing issues where applicable, +- add tests to maintain 100% test coverage, +- update the documentation as needed, and +- ensure the source code is amalgamated. + +We describe all points in detail below. + +All contributions (including pull requests) must agree to the [Developer Certificate of Origin (DCO) version 1.1](https://developercertificate.org). This is exactly the same one created and used by the Linux kernel developers and posted on . This is a developer's certification that he or she has the right to submit the patch for inclusion into the project. + +## How to... + +### Describe your changes + +This library is primarily maintained as a spare-time project. As such, I cannot make any guarantee how quickly changes are merged and released. Therefore, it is very important to make the review as smooth as possible by explaining not only *what* you changed, but *why*. This rationale can be very valuable down the road when improvements or bugs are discussed years later. + +### Reference an existing issue + +[Link a pull request to an issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue) to clarify that a fix is forthcoming and which issue can be closed after merging. Only a few cases (e.g., fixing typos) do not require prior discussions. + +### Write tests + +The library has an extensive test suite that currently covers [100 %](https://coveralls.io/github/nlohmann/json) of the library's code. These tests are crucial to maintain API stability and give future contributors confidence that they do not accidentally break things. As Titus Winters aptly put it: + +> If you liked it, you should have put a test on it. + +#### Run the tests + +First, ensure the test suite runs before making any changes: + +``` +$ cmake -S. -B build +$ cmake --build build -j 10 +$ ctest --test-dir build -j 10 +``` + +The test suite should report: + +``` +100% tests passed, 0 tests failed out of 98 +``` + +#### Add tests + +The tests are located in [`tests/src/unit-*.cpp`](https://github.com/nlohmann/json/tree/develop/tests/src) and contain [doctest assertions](https://github.com/doctest/doctest/blob/master/doc/markdown/assertions.md) like `CHECK`. The tests are structured along the features of the library or the nature of the tests. Usually, it should be clear from the context which existing file needs to be extended, and only very few cases require creating new test files. + +When fixing a bug, edit `unit-regression2.cpp` and add a section referencing the fixed issue. + +#### Exceptions + +When you test exceptions, please use `CHECK_THROWS_WITH_AS` which also takes the `what()` argument of the thrown exception into account. + +#### Coverage + +If test coverage decreases, an automatic warning comment will be posted on the pull request. You can access a code coverage report as an artifact to the “Ubuntu” workflow. + +### Update the documentation + +The [main documentation](https://json.nlohmann.me) of the library is generated from the files [`docs/mkdocs/docs`](https://github.com/nlohmann/json/blob/develop/docs/mkdocs/docs). This folder contains dedicated pages for [certain features](https://github.com/nlohmann/json/tree/develop/docs/mkdocs/docs/features), a list of [all exceptions](https://github.com/nlohmann/json/blob/develop/docs/mkdocs/docs/home/exceptions.md), and [extensive API documentation](https://github.com/nlohmann/json/tree/develop/docs/mkdocs/docs/api) with details on every public API function. + +Build the documentation locally using: + +``` +make install_venv -C docs/mkdocs +make serve -C docs/mkdocs +``` + +The documentation will then be available at . See the documentation of [mkdocs](https://www.mkdocs.org) and [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/) for more information. + +### Amalgamate the source code + +The single-header files [`single_include/nlohmann/json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) and [`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) are **generated** from the source files in the [`include/nlohmann` directory](https://github.com/nlohmann/json/tree/develop/include/nlohmann). **Do not** edit the files directly; instead, modify the include/nlohmann sources and regenerate the files by executing: + +``` +make amalgamate +``` + +Running `make amalgamate` will also apply automatic formatting to the source files using [`Artistic Style`](https://astyle.sourceforge.net/). This formatting may modify your source files in-place. Be certain to review and commit any changes to avoid unintended formatting diffs in commits. + +## Recommended documentation + +- The library’s [README file](https://github.com/nlohmann/json/blob/master/README.md) is an excellent starting point to understand its functionality. +- The [documentation page](https://json.nlohmann.me) is the reference documentation of the library. +- [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259) is the reference for the JavaScript Object Notation (JSON) Data Interchange Format. + +## Please don't... + +Certain contributions are not helpful. + +### Break the public API + +We take pride in the library being used by [numerous customers across various industries](https://json.nlohmann.me/home/customers/). They all rely on the guarantees provided by [semantic versioning](https://semver.org). Please do not change the library such that the public API of the 3.x.y version is broken. This includes: + +- Changing function signatures (altering parameter types, return types, number of parameters) or changing the const-ness of member functions. +- Removing functions. +- Renaming functions or classes. +- Changing exception handling. +- Changing exception ids. +- Changing access specifiers. +- Changing default arguments. + +Although these guidelines may seem restrictive, they are essential for maintaining the library’s utility. + +Breaking changes may be introduced when they are guarded with a feature macro such as [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/) which allows selectively changing the behavior of the library. In next steps, the current behavior can then be deprecated. Using feature macros then allows users to test their code against the library in the next major release. + +### Break C++11 language conformance + +This library is designed to work with C++11 and later. This means that any [supported C++11 compiler](https://github.com/nlohmann/json/blob/master/README.md#supported-compilers) should compile the library without problems. Some compilers like GCC 4.7 (and earlier), Clang 3.3 (and earlier), or Microsoft Visual Studio 13.0 and earlier are known not to work due to missing or incomplete C++11 support. + +Please do not add features that do not work with the mentioned supported compilers. Please guard features from C++14 and later against the respective [`JSON_HAS_CPP_14`](https://json.nlohmann.me/api/macros/json_has_cpp_11/) macros. + +### Break JSON conformance + +Please refrain from proposing changes that would **break [JSON](https://datatracker.ietf.org/doc/html/rfc8259) conformance**. If you propose a conformant extension of JSON to be supported by the library, please motivate this extension. + +## Wanted + +The following areas really need contribution and are always welcomed: + +- Extending the **continuous integration** toward more exotic compilers such as Android NDK, Intel's Compiler, or the bleeding-edge versions Clang. +- Improving the efficiency of the **JSON parser**. The current parser is implemented as a naive recursive descent parser with hand-coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the `json.hpp` header, and I am not aware of approaches similar to [`re2c`](http://re2c.org) for parsing. +- Extending and updating existing **benchmarks** to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting. + +We look forward to your contributions and collaboration to enhance the library! diff --git a/community/governance.md b/community/governance.md new file mode 100644 index 000000000..7da85f3fe --- /dev/null +++ b/community/governance.md @@ -0,0 +1,122 @@ +# Governance + +The governance model for the JSON for Modern C++ project is a **Benevolent Dictator for Life (BDFL)** structure. As the +sole maintainer, [Niels Lohmann](https://github.com/nlohmann) is responsible for all key aspects of the project. The +project governance may evolve as the project grows, but any changes will be documented here and communicated to +contributors. + +## Overview + +This project is led by a benevolent dictator, [Niels Lohmann](https://github.com/nlohmann), and managed by the +community. That is, the community actively contributes to the day-to-day maintenance of the project, but the general +strategic line is drawn by the benevolent dictator. In case of disagreement, they have the last word. It is the +benevolent dictator’s job to resolve disputes within the community and to ensure that the project is able to progress in +a coordinated way. In turn, it is the community’s job to guide the decisions of the benevolent dictator through active +engagement and contribution. + +## Roles and responsibilities + +### Benevolent dictator (project lead) + +Typically, the benevolent dictator, or project lead, is self-appointed. However, because the community always has the +ability to fork, this person is fully answerable to the community. The project lead’s role is a difficult one: they set +the strategic objectives of the project and communicate these clearly to the community. They also have to understand the +community as a whole and strive to satisfy as many conflicting needs as possible, while ensuring that the project +survives in the long term. + +In many ways, the role of the benevolent dictator is less about dictatorship and more about diplomacy. The key is to +ensure that, as the project expands, the right people are given influence over it and the community rallies behind the +vision of the project lead. The lead’s job is then to ensure that the committers (see below) make the right decisions on +behalf of the project. Generally speaking, as long as the committers are aligned with the project’s strategy, the +project lead will allow them to proceed as they desire. + +### Committers + +Committers are contributors who have made several valuable contributions to the project and are now relied upon to both +write code directly to the repository and screen the contributions of others. In many cases they are programmers but it +is also possible that they contribute in a different role. Typically, a committer will focus on a specific aspect of the +project, and will bring a level of expertise and understanding that earns them the respect of the community and the +project lead. The role of committer is not an official one, it is simply a position that influential members of the +community will find themselves in as the project lead looks to them for guidance and support. + +Committers have no authority over the overall direction of the project. However, they do have the ear of the project +lead. It is a committer’s job to ensure that the lead is aware of the community’s needs and collective objectives, and +to help develop or elicit appropriate contributions to the project. Often, committers are given informal control over +their specific areas of responsibility, and are assigned rights to directly modify certain areas of the source code. +That is, although committers do not have explicit decision-making authority, they will often find that their actions are +synonymous with the decisions made by the lead. + +### Contributors + +Contributors are community members who either have no desire to become committers, or have not yet been given the +opportunity by the benevolent dictator. They make valuable contributions, such as those outlined in the list below, but +generally do not have the authority to make direct changes to the project code. Contributors engage with the project +through communication tools, such as email lists, and via reports and patches attached to issues in the issue tracker, +as detailed in our community tools document. + +Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements +and no selection process. To become a contributor, a community member simply has to perform one or more actions that are +beneficial to the project. + +Some contributors will already be engaging with the project as users, but will also find themselves doing one or more of +the following: + +- supporting new users (current users often provide the most effective new user support) +- reporting bugs +- identifying requirements +- supplying graphics and web design +- programming +- assisting with project infrastructure +- writing documentation +- fixing bugs +- adding features + +As contributors gain experience and familiarity with the project, they may find that the project lead starts relying on +them more and more. When this begins to happen, they gradually adopt the role of committer, as described above. + +### Users + +Users are community members who have a need for the project. They are the most important members of the community: +without them, the project would have no purpose. Anyone can be a user; there are no specific requirements. + +Users should be encouraged to participate in the life of the project and the community as much as possible. User +contributions enable the project team to ensure that they are satisfying the needs of those users. Common user +activities include (but are not limited to): + +- evangelising about the project +- informing developers of project strengths and weaknesses from a new user’s perspective +- providing moral support (a ‘thank you’ goes a long way) +- providing financial support + +Users who continue to engage with the project and its community will often find themselves becoming more and more +involved. Such users may then go on to become contributors, as described above. + +## Support + +All participants in the community are encouraged to provide support for new users within the project management +infrastructure. This support is provided as a way of growing the community. Those seeking support should recognise that +all support activity within the project is voluntary and is therefore provided as and when time allows. A user requiring +guaranteed response times or results should therefore seek to purchase a support contract from a vendor. (Of course, +that vendor should be an active member of the community.) However, for those willing to engage with the project on its +own terms, and willing to help support other users, the community support channels are ideal. + +## Contribution Process + +Anyone can contribute to the project, regardless of their skills, as there are many ways to contribute. For instance, a +contributor might be active on the project mailing list and issue tracker, or might supply patches. The various ways of +contributing are described in more detail in our roles in open source document. + +The developer mailing list is the most appropriate place for a contributor to ask for help when making their first +contribution. + +## Decision-Making Process + +The benevolent dictatorship model does not need a formal conflict resolution process, since the project lead’s word is +final. If the community chooses to question the wisdom of the actions of a committer, the project lead can review their +decisions by checking the email archives, and either uphold or reverse them. + +--- + +!!! quote "Source" + + The text was taken from http://oss-watch.ac.uk/resources/benevolentdictatorgovernancemodel. diff --git a/community/governance/index.html b/community/governance/index.html index 8b6c2e660..edeb77992 100644 --- a/community/governance/index.html +++ b/community/governance/index.html @@ -1 +1 @@ - Governance - JSON for Modern C++

Governance

The governance model for the JSON for Modern C++ project is a Benevolent Dictator for Life (BDFL) structure. As the sole maintainer, Niels Lohmann is responsible for all key aspects of the project. The project governance may evolve as the project grows, but any changes will be documented here and communicated to contributors.

Overview

This project is led by a benevolent dictator, Niels Lohmann, and managed by the community. That is, the community actively contributes to the day-to-day maintenance of the project, but the general strategic line is drawn by the benevolent dictator. In case of disagreement, they have the last word. It is the benevolent dictator’s job to resolve disputes within the community and to ensure that the project is able to progress in a coordinated way. In turn, it is the community’s job to guide the decisions of the benevolent dictator through active engagement and contribution.

Roles and responsibilities

Benevolent dictator (project lead)

Typically, the benevolent dictator, or project lead, is self-appointed. However, because the community always has the ability to fork, this person is fully answerable to the community. The project lead’s role is a difficult one: they set the strategic objectives of the project and communicate these clearly to the community. They also have to understand the community as a whole and strive to satisfy as many conflicting needs as possible, while ensuring that the project survives in the long term.

In many ways, the role of the benevolent dictator is less about dictatorship and more about diplomacy. The key is to ensure that, as the project expands, the right people are given influence over it and the community rallies behind the vision of the project lead. The lead’s job is then to ensure that the committers (see below) make the right decisions on behalf of the project. Generally speaking, as long as the committers are aligned with the project’s strategy, the project lead will allow them to proceed as they desire.

Committers

Committers are contributors who have made several valuable contributions to the project and are now relied upon to both write code directly to the repository and screen the contributions of others. In many cases they are programmers but it is also possible that they contribute in a different role. Typically, a committer will focus on a specific aspect of the project, and will bring a level of expertise and understanding that earns them the respect of the community and the project lead. The role of committer is not an official one, it is simply a position that influential members of the community will find themselves in as the project lead looks to them for guidance and support.

Committers have no authority over the overall direction of the project. However, they do have the ear of the project lead. It is a committer’s job to ensure that the lead is aware of the community’s needs and collective objectives, and to help develop or elicit appropriate contributions to the project. Often, committers are given informal control over their specific areas of responsibility, and are assigned rights to directly modify certain areas of the source code. That is, although committers do not have explicit decision-making authority, they will often find that their actions are synonymous with the decisions made by the lead.

Contributors

Contributors are community members who either have no desire to become committers, or have not yet been given the opportunity by the benevolent dictator. They make valuable contributions, such as those outlined in the list below, but generally do not have the authority to make direct changes to the project code. Contributors engage with the project through communication tools, such as email lists, and via reports and patches attached to issues in the issue tracker, as detailed in our community tools document.

Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements and no selection process. To become a contributor, a community member simply has to perform one or more actions that are beneficial to the project.

Some contributors will already be engaging with the project as users, but will also find themselves doing one or more of the following:

  • supporting new users (current users often provide the most effective new user support)
  • reporting bugs
  • identifying requirements
  • supplying graphics and web design
  • programming
  • assisting with project infrastructure
  • writing documentation
  • fixing bugs
  • adding features

As contributors gain experience and familiarity with the project, they may find that the project lead starts relying on them more and more. When this begins to happen, they gradually adopt the role of committer, as described above.

Users

Users are community members who have a need for the project. They are the most important members of the community: without them, the project would have no purpose. Anyone can be a user; there are no specific requirements.

Users should be encouraged to participate in the life of the project and the community as much as possible. User contributions enable the project team to ensure that they are satisfying the needs of those users. Common user activities include (but are not limited to):

  • evangelising about the project
  • informing developers of project strengths and weaknesses from a new user’s perspective
  • providing moral support (a ‘thank you’ goes a long way)
  • providing financial support

Users who continue to engage with the project and its community will often find themselves becoming more and more involved. Such users may then go on to become contributors, as described above.

Support

All participants in the community are encouraged to provide support for new users within the project management infrastructure. This support is provided as a way of growing the community. Those seeking support should recognise that all support activity within the project is voluntary and is therefore provided as and when time allows. A user requiring guaranteed response times or results should therefore seek to purchase a support contract from a vendor. (Of course, that vendor should be an active member of the community.) However, for those willing to engage with the project on its own terms, and willing to help support other users, the community support channels are ideal.

Contribution Process

Anyone can contribute to the project, regardless of their skills, as there are many ways to contribute. For instance, a contributor might be active on the project mailing list and issue tracker, or might supply patches. The various ways of contributing are described in more detail in our roles in open source document.

The developer mailing list is the most appropriate place for a contributor to ask for help when making their first contribution.

Decision-Making Process

The benevolent dictatorship model does not need a formal conflict resolution process, since the project lead’s word is final. If the community chooses to question the wisdom of the actions of a committer, the project lead can review their decisions by checking the email archives, and either uphold or reverse them.


\ No newline at end of file + Governance - JSON for Modern C++

Governance

The governance model for the JSON for Modern C++ project is a Benevolent Dictator for Life (BDFL) structure. As the sole maintainer, Niels Lohmann is responsible for all key aspects of the project. The project governance may evolve as the project grows, but any changes will be documented here and communicated to contributors.

Overview

This project is led by a benevolent dictator, Niels Lohmann, and managed by the community. That is, the community actively contributes to the day-to-day maintenance of the project, but the general strategic line is drawn by the benevolent dictator. In case of disagreement, they have the last word. It is the benevolent dictator’s job to resolve disputes within the community and to ensure that the project is able to progress in a coordinated way. In turn, it is the community’s job to guide the decisions of the benevolent dictator through active engagement and contribution.

Roles and responsibilities

Benevolent dictator (project lead)

Typically, the benevolent dictator, or project lead, is self-appointed. However, because the community always has the ability to fork, this person is fully answerable to the community. The project lead’s role is a difficult one: they set the strategic objectives of the project and communicate these clearly to the community. They also have to understand the community as a whole and strive to satisfy as many conflicting needs as possible, while ensuring that the project survives in the long term.

In many ways, the role of the benevolent dictator is less about dictatorship and more about diplomacy. The key is to ensure that, as the project expands, the right people are given influence over it and the community rallies behind the vision of the project lead. The lead’s job is then to ensure that the committers (see below) make the right decisions on behalf of the project. Generally speaking, as long as the committers are aligned with the project’s strategy, the project lead will allow them to proceed as they desire.

Committers

Committers are contributors who have made several valuable contributions to the project and are now relied upon to both write code directly to the repository and screen the contributions of others. In many cases they are programmers but it is also possible that they contribute in a different role. Typically, a committer will focus on a specific aspect of the project, and will bring a level of expertise and understanding that earns them the respect of the community and the project lead. The role of committer is not an official one, it is simply a position that influential members of the community will find themselves in as the project lead looks to them for guidance and support.

Committers have no authority over the overall direction of the project. However, they do have the ear of the project lead. It is a committer’s job to ensure that the lead is aware of the community’s needs and collective objectives, and to help develop or elicit appropriate contributions to the project. Often, committers are given informal control over their specific areas of responsibility, and are assigned rights to directly modify certain areas of the source code. That is, although committers do not have explicit decision-making authority, they will often find that their actions are synonymous with the decisions made by the lead.

Contributors

Contributors are community members who either have no desire to become committers, or have not yet been given the opportunity by the benevolent dictator. They make valuable contributions, such as those outlined in the list below, but generally do not have the authority to make direct changes to the project code. Contributors engage with the project through communication tools, such as email lists, and via reports and patches attached to issues in the issue tracker, as detailed in our community tools document.

Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements and no selection process. To become a contributor, a community member simply has to perform one or more actions that are beneficial to the project.

Some contributors will already be engaging with the project as users, but will also find themselves doing one or more of the following:

  • supporting new users (current users often provide the most effective new user support)
  • reporting bugs
  • identifying requirements
  • supplying graphics and web design
  • programming
  • assisting with project infrastructure
  • writing documentation
  • fixing bugs
  • adding features

As contributors gain experience and familiarity with the project, they may find that the project lead starts relying on them more and more. When this begins to happen, they gradually adopt the role of committer, as described above.

Users

Users are community members who have a need for the project. They are the most important members of the community: without them, the project would have no purpose. Anyone can be a user; there are no specific requirements.

Users should be encouraged to participate in the life of the project and the community as much as possible. User contributions enable the project team to ensure that they are satisfying the needs of those users. Common user activities include (but are not limited to):

  • evangelising about the project
  • informing developers of project strengths and weaknesses from a new user’s perspective
  • providing moral support (a ‘thank you’ goes a long way)
  • providing financial support

Users who continue to engage with the project and its community will often find themselves becoming more and more involved. Such users may then go on to become contributors, as described above.

Support

All participants in the community are encouraged to provide support for new users within the project management infrastructure. This support is provided as a way of growing the community. Those seeking support should recognise that all support activity within the project is voluntary and is therefore provided as and when time allows. A user requiring guaranteed response times or results should therefore seek to purchase a support contract from a vendor. (Of course, that vendor should be an active member of the community.) However, for those willing to engage with the project on its own terms, and willing to help support other users, the community support channels are ideal.

Contribution Process

Anyone can contribute to the project, regardless of their skills, as there are many ways to contribute. For instance, a contributor might be active on the project mailing list and issue tracker, or might supply patches. The various ways of contributing are described in more detail in our roles in open source document.

The developer mailing list is the most appropriate place for a contributor to ask for help when making their first contribution.

Decision-Making Process

The benevolent dictatorship model does not need a formal conflict resolution process, since the project lead’s word is final. If the community chooses to question the wisdom of the actions of a committer, the project lead can review their decisions by checking the email archives, and either uphold or reverse them.


\ No newline at end of file diff --git a/community/governance/index.md b/community/governance/index.md new file mode 100644 index 000000000..c088c3235 --- /dev/null +++ b/community/governance/index.md @@ -0,0 +1,74 @@ +# Governance + +The governance model for the JSON for Modern C++ project is a **Benevolent Dictator for Life (BDFL)** structure. As the sole maintainer, [Niels Lohmann](https://github.com/nlohmann) is responsible for all key aspects of the project. The project governance may evolve as the project grows, but any changes will be documented here and communicated to contributors. + +## Overview + +This project is led by a benevolent dictator, [Niels Lohmann](https://github.com/nlohmann), and managed by the community. That is, the community actively contributes to the day-to-day maintenance of the project, but the general strategic line is drawn by the benevolent dictator. In case of disagreement, they have the last word. It is the benevolent dictator’s job to resolve disputes within the community and to ensure that the project is able to progress in a coordinated way. In turn, it is the community’s job to guide the decisions of the benevolent dictator through active engagement and contribution. + +## Roles and responsibilities + +### Benevolent dictator (project lead) + +Typically, the benevolent dictator, or project lead, is self-appointed. However, because the community always has the ability to fork, this person is fully answerable to the community. The project lead’s role is a difficult one: they set the strategic objectives of the project and communicate these clearly to the community. They also have to understand the community as a whole and strive to satisfy as many conflicting needs as possible, while ensuring that the project survives in the long term. + +In many ways, the role of the benevolent dictator is less about dictatorship and more about diplomacy. The key is to ensure that, as the project expands, the right people are given influence over it and the community rallies behind the vision of the project lead. The lead’s job is then to ensure that the committers (see below) make the right decisions on behalf of the project. Generally speaking, as long as the committers are aligned with the project’s strategy, the project lead will allow them to proceed as they desire. + +### Committers + +Committers are contributors who have made several valuable contributions to the project and are now relied upon to both write code directly to the repository and screen the contributions of others. In many cases they are programmers but it is also possible that they contribute in a different role. Typically, a committer will focus on a specific aspect of the project, and will bring a level of expertise and understanding that earns them the respect of the community and the project lead. The role of committer is not an official one, it is simply a position that influential members of the community will find themselves in as the project lead looks to them for guidance and support. + +Committers have no authority over the overall direction of the project. However, they do have the ear of the project lead. It is a committer’s job to ensure that the lead is aware of the community’s needs and collective objectives, and to help develop or elicit appropriate contributions to the project. Often, committers are given informal control over their specific areas of responsibility, and are assigned rights to directly modify certain areas of the source code. That is, although committers do not have explicit decision-making authority, they will often find that their actions are synonymous with the decisions made by the lead. + +### Contributors + +Contributors are community members who either have no desire to become committers, or have not yet been given the opportunity by the benevolent dictator. They make valuable contributions, such as those outlined in the list below, but generally do not have the authority to make direct changes to the project code. Contributors engage with the project through communication tools, such as email lists, and via reports and patches attached to issues in the issue tracker, as detailed in our community tools document. + +Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements and no selection process. To become a contributor, a community member simply has to perform one or more actions that are beneficial to the project. + +Some contributors will already be engaging with the project as users, but will also find themselves doing one or more of the following: + +- supporting new users (current users often provide the most effective new user support) +- reporting bugs +- identifying requirements +- supplying graphics and web design +- programming +- assisting with project infrastructure +- writing documentation +- fixing bugs +- adding features + +As contributors gain experience and familiarity with the project, they may find that the project lead starts relying on them more and more. When this begins to happen, they gradually adopt the role of committer, as described above. + +### Users + +Users are community members who have a need for the project. They are the most important members of the community: without them, the project would have no purpose. Anyone can be a user; there are no specific requirements. + +Users should be encouraged to participate in the life of the project and the community as much as possible. User contributions enable the project team to ensure that they are satisfying the needs of those users. Common user activities include (but are not limited to): + +- evangelising about the project +- informing developers of project strengths and weaknesses from a new user’s perspective +- providing moral support (a ‘thank you’ goes a long way) +- providing financial support + +Users who continue to engage with the project and its community will often find themselves becoming more and more involved. Such users may then go on to become contributors, as described above. + +## Support + +All participants in the community are encouraged to provide support for new users within the project management infrastructure. This support is provided as a way of growing the community. Those seeking support should recognise that all support activity within the project is voluntary and is therefore provided as and when time allows. A user requiring guaranteed response times or results should therefore seek to purchase a support contract from a vendor. (Of course, that vendor should be an active member of the community.) However, for those willing to engage with the project on its own terms, and willing to help support other users, the community support channels are ideal. + +## Contribution Process + +Anyone can contribute to the project, regardless of their skills, as there are many ways to contribute. For instance, a contributor might be active on the project mailing list and issue tracker, or might supply patches. The various ways of contributing are described in more detail in our roles in open source document. + +The developer mailing list is the most appropriate place for a contributor to ask for help when making their first contribution. + +## Decision-Making Process + +The benevolent dictatorship model does not need a formal conflict resolution process, since the project lead’s word is final. If the community chooses to question the wisdom of the actions of a committer, the project lead can review their decisions by checking the email archives, and either uphold or reverse them. + +______________________________________________________________________ + +Source + +The text was taken from . diff --git a/community/index.html b/community/index.html index a622bc3f7..b51be7897 100644 --- a/community/index.html +++ b/community/index.html @@ -1 +1 @@ - Community - JSON for Modern C++
\ No newline at end of file + Community - JSON for Modern C++
\ No newline at end of file diff --git a/community/index.md b/community/index.md new file mode 100644 index 000000000..75428364f --- /dev/null +++ b/community/index.md @@ -0,0 +1,7 @@ +# Community + +- [Code of Conduct](https://json.nlohmann.me/community/code_of_conduct/index.md) - the rules and norms of this project +- [Contribution Guidelines](https://json.nlohmann.me/community/contribution_guidelines/index.md) - guidelines how to contribute to this project +- [Governance](https://json.nlohmann.me/community/governance/index.md) - the governance model of this project +- [Quality Assurance](https://json.nlohmann.me/community/quality_assurance/index.md) - how the quality of this project is assured +- [Security Policy](https://json.nlohmann.me/community/security_policy/index.md) - the security policy of the project diff --git a/community/quality_assurance.md b/community/quality_assurance.md new file mode 100644 index 000000000..31990fa83 --- /dev/null +++ b/community/quality_assurance.md @@ -0,0 +1,227 @@ +# Quality assurance + +Ensuring quality is paramount for this project, particularly because [numerous other projects](../home/customers.md) +depend on it. Each commit to the library undergoes rigorous checks against the following requirements, and any +violations will result in a failed build. + +## C++ language compliance and compiler compatibility + +!!! success "Requirement: Compiler support" + + Any compiler with complete C++11 support can compile the library without warnings. + +- [x] The library is compiled with 50+ different C++ compilers with different operating systems and platforms, + including the oldest versions known to compile the library. + + ??? abstract "Compilers used in continuous integration" + + | Compiler | Architecture | Operating System | CI | + |----------------------------------------------|--------------|-----------------------------------|-----------| + | AppleClang 15.0.0.15000040; Xcode 15.0.1 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000100; Xcode 15.1 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000100; Xcode 15.2 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000309; Xcode 15.3 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000309; Xcode 15.4 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 16.0.0.16000026; Xcode 16 | arm64 | macOS 15.2 (Sequoia) | GitHub | + | AppleClang 16.0.0.16000026; Xcode 16.1 | arm64 | macOS 15.2 (Sequoia) | GitHub | + | AppleClang 16.0.0.16000026; Xcode 16.2 | arm64 | macOS 15.2 (Sequoia) | GitHub | + | AppleClang 17.0.0.17000013; Xcode 16.3 | arm64 | macOS 15.5 (Sequoia) | GitHub | + | AppleClang 17.0.0.17000013; Xcode 16.4 | arm64 | macOS 15.5 (Sequoia) | GitHub | + | AppleClang 17.0.0.17000319; Xcode 26.0.1 | arm64 | macOS 15.5 (Sequoia) | GitHub | + | Clang 3.4.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.5.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.6.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.7.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.8.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.9.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 4.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 5.0.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 6.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 7.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 8.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 9.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 10.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 11.0.1 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 11.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 12.0.1 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 12.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 13.0.1 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 13.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 14.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 14.0.6 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 15.0.7 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 15.0.7 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 16.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 16.0.6 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 17.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 18.1.8 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 18.1.8 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 19.1.5 with MSVC-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 19.1.7 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 19.1.7 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 20.1.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 20.1.8 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 21.1.8 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | CUDA 11.0.221 (nvcc) | x86_64 | Ubuntu 20.04 LTS | GitHub | + | Emscripten 4.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 4.8.5 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 4.9.3 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 5.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 6.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 7.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 8.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 9.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 9.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 9.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 10.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 11.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 11.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 12.2.0 (MinGW-W64 i686-ucrt-posix-dwarf) | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | GNU 12.2.0 (MinGW-W64 x86_64-ucrt-posix-seh) | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | GNU 12.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 13.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 14.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 15.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 16.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 16.1.0 | arm64 | Linux 6.1.100 | Cirrus CI | + | icpc (ICC) 2021.5.0 20211109 | x86_64 | Ubuntu 20.04.3 LTS | GitHub | + | icpx (Intel oneAPI DPC++/C++) 2025.3.2 | x86_64 | Ubuntu 24.04 LTS | GitHub | + | nvc++ (NVIDIA HPC SDK) 25.5-0 | x86_64 | Ubuntu 22.04 LTS | GitHub | + | MSVC 19.0.24241.7 | x86 | Windows 8.1 | AppVeyor | + | MSVC 19.16.27035.0 | x86 | Windows-10 (Build 14393) | AppVeyor | + | MSVC 19.29.30157.0 | x86 | Windows-10 (Build 17763) | AppVeyor | + | MSVC 19.44.35207.0 | arm64 | Windows 11 (Build 26200) | GitHub | + | MSVC 19.44.35214.0 | x86 | Windows Server 2022 (Build 20348) | GitHub | + | MSVC 19.44.35214.0 | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | MSVC 19.51.36231.0 | x86 | Windows Server 2025 (Build 26100) | GitHub | + | MSVC 19.51.36231.0 | x86_64 | Windows Server 2025 (Build 26100) | GitHub | + +- [x] The library is compiled with all C++ language revisions (C++11, C++14, C++17, C++20, C++23, and C++26) to detect + and fix language deprecations early. +- [x] The library is checked for compiler warnings: + - On Clang, `-Weverything` is used with 8 exceptions. + + ??? abstract "Clang warnings" + + ```cmake + --8<-- "../../../cmake/clang_flags.cmake" + ``` + + - On GCC, 300+ warnings are enabled with 8 exceptions. + + ??? abstract "GCC warnings" + + ```cmake + --8<-- "../../../cmake/gcc_flags.cmake" + ``` + +## C++ standard library compliance + +!!! success "Requirement: No prerequisites" + + The library has no prerequisites other than the Standard Template Library (STL). + +- [x] The library is compiled and tested with both [libc++](https://libcxx.llvm.org) and + [libstdc++](https://gcc.gnu.org/onlinedocs/libstdc++/) to detect subtle differences or incompatibilities. +- [x] The code checked with [Include What You Use (IWYU)](https://include-what-you-use.org) that all required standard + headers are included. +- [x] On Windows, the library is compiled with `` being included to detect and avoid common bugs. +- [x] The library is compiled with exceptions disabled to support alternative means of error handling. + +## Stable public API + +!!! success "Requirement: Stable public API" + + Any change to the library does not break the public API. + +- [x] All public API functions are tested with a variety of arguments. +- [x] The library is compiled and tested with different template arguments for number, string, array, and object types. +- [x] Unit tests cover all lines of the code base. +- [x] Every exception of the library is thrown in the test suite, and the error messages and exception ids are checked. + +!!! success "Requirement: Complete documentation" + + The public API is extensively documented. + +- [x] Every public API function has a dedicated page in the + [API reference documentation](https://json.nlohmann.me/api/basic_json/) with a self-contained code example. +- [x] All examples in the documentation are tested, and changes in their output are treated as an error. + +## Robust input processing + +!!! success "Requirement: Standards compliance" + + The library is compliant to JSON as defined in [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259). + +- [x] The lexer is tested with all valid Unicode code points and all prefixes of all invalid Unicode code points. +- [x] The parser is tested against extensive correctness suites for JSON compliance. +- [x] In addition, the library is continuously fuzz-tested at [OSS-Fuzz](https://google.github.io/oss-fuzz/) where the + library is checked against billions of inputs. + +## Static analysis + +!!! success "Requirement: State-of-the-art code analysis" + + The code is checked with state-of-the-art static code analysis tools. + +- [x] The code is checked with the latest [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/). + + ??? abstract "Clang-Tidy configuration (.clang-tidy)" + + ```ini + --8<-- "../../../.clang-tidy" + ``` + +- [x] The code is checked with the latest [Cppcheck](https://cppcheck.sourceforge.io) with all warnings enabled. +- [x] The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) with 89 enabled + rules. +- [x] The code is checked with [Infer](https://fbinfer.com). +- [x] The code is checked with [Codacy](https://app.codacy.com/gh/nlohmann/json/dashboard). + +## Dynamic analysis + +!!! success "Requirement: Correctness" + + The library is checked for memory correctness and absence of undefined behavior. + +- [x] The test suite is executed with enabled [runtime assertions](https://json.nlohmann.me/features/assertions/) to + check invariants and preconditions of functions to detect undefined behavior. +- [x] The test suite is executed with [Valgrind](https://valgrind.org) (Memcheck) to detect memory leaks. +- [x] The test suite is executed with [Sanitizers](https://github.com/google/sanitizers) (address sanitizer, undefined + behavior sanitizer, integer overflow detection, nullability violations). + +## Style check + +!!! success "Requirement: Common code style" + + A common code style is used throughout all code files of the library. + +- [x] The code is formatted with [Artistic Style](https://astyle.sourceforge.net) (astyle) against a style configuration + that is also enforced in the CI. + + ??? abstract "Astyle configuration (tools/astyle/.astylerc)" + + ```ini + --8<-- "../../../tools/astyle/.astylerc" + ``` + +- [x] The code style is checked with [cpplint](https://github.com/cpplint/cpplint) with 61 enabled rules. + +## Simple integration + +!!! success "Requirement: Single header" + + The library can be used by adding a single header to a C++ project. + +- [x] An amalgamation script is used to check if the source code is exposed as a self-contained single-header file. +- [x] The test suite is checked against the amalgamated source file as well as the individual source file. + +!!! success "Requirement: CMake as primary development tool" + + All library functions are exposed and usable by CMake. + +- [x] All library options are exposed as [CMake options](https://json.nlohmann.me/integration/cmake/) and tested. +- [x] The library is tested against relevant CMake versions: + - CMake 3.5 (the earliest supported) + - CMake 3.31.6 (the latest 3.x release) + - CMake 4.0.0 (a very recent release) diff --git a/community/quality_assurance/index.html b/community/quality_assurance/index.html index 2b531b32c..0e24e340e 100644 --- a/community/quality_assurance/index.html +++ b/community/quality_assurance/index.html @@ -548,4 +548,4 @@ # for the linux (LF) line end style --lineend=linux -
  • The code style is checked with cpplint with 61 enabled rules.

  • Simple integration

    Requirement: Single header

    The library can be used by adding a single header to a C++ project.

    • An amalgamation script is used to check if the source code is exposed as a self-contained single-header file.
    • The test suite is checked against the amalgamated source file as well as the individual source file.

    Requirement: CMake as primary development tool

    All library functions are exposed and usable by CMake.

    • All library options are exposed as CMake options and tested.
    • The library is tested against relevant CMake versions:
    • CMake 3.5 (the earliest supported)
    • CMake 3.31.6 (the latest 3.x release)
    • CMake 4.0.0 (a very recent release)
    \ No newline at end of file +
  • The code style is checked with cpplint with 61 enabled rules.

  • Simple integration

    Requirement: Single header

    The library can be used by adding a single header to a C++ project.

    • An amalgamation script is used to check if the source code is exposed as a self-contained single-header file.
    • The test suite is checked against the amalgamated source file as well as the individual source file.

    Requirement: CMake as primary development tool

    All library functions are exposed and usable by CMake.

    • All library options are exposed as CMake options and tested.
    • The library is tested against relevant CMake versions:
    • CMake 3.5 (the earliest supported)
    • CMake 3.31.6 (the latest 3.x release)
    • CMake 4.0.0 (a very recent release)
    \ No newline at end of file diff --git a/community/quality_assurance/index.md b/community/quality_assurance/index.md new file mode 100644 index 000000000..1dc6b6e6f --- /dev/null +++ b/community/quality_assurance/index.md @@ -0,0 +1,766 @@ +# Quality assurance + +Ensuring quality is paramount for this project, particularly because [numerous other projects](https://json.nlohmann.me/home/customers/index.md) depend on it. Each commit to the library undergoes rigorous checks against the following requirements, and any violations will result in a failed build. + +## C++ language compliance and compiler compatibility + +Requirement: Compiler support + +Any compiler with complete C++11 support can compile the library without warnings. + +- The library is compiled with 50+ different C++ compilers with different operating systems and platforms, including the oldest versions known to compile the library. + + Compilers used in continuous integration + + | Compiler | Architecture | Operating System | CI | + | -------------------------------------------- | ------------ | --------------------------------- | --------- | + | AppleClang 15.0.0.15000040; Xcode 15.0.1 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000100; Xcode 15.1 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000100; Xcode 15.2 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000309; Xcode 15.3 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 15.0.0.15000309; Xcode 15.4 | arm64 | macOS 14.7.2 (Sonoma) | GitHub | + | AppleClang 16.0.0.16000026; Xcode 16 | arm64 | macOS 15.2 (Sequoia) | GitHub | + | AppleClang 16.0.0.16000026; Xcode 16.1 | arm64 | macOS 15.2 (Sequoia) | GitHub | + | AppleClang 16.0.0.16000026; Xcode 16.2 | arm64 | macOS 15.2 (Sequoia) | GitHub | + | AppleClang 17.0.0.17000013; Xcode 16.3 | arm64 | macOS 15.5 (Sequoia) | GitHub | + | AppleClang 17.0.0.17000013; Xcode 16.4 | arm64 | macOS 15.5 (Sequoia) | GitHub | + | AppleClang 17.0.0.17000319; Xcode 26.0.1 | arm64 | macOS 15.5 (Sequoia) | GitHub | + | Clang 3.4.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.5.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.6.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.7.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.8.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 3.9.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 4.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 5.0.2 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 6.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 7.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 8.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 9.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 10.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 11.0.1 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 11.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 12.0.1 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 12.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 13.0.1 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 13.0.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 14.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 14.0.6 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 15.0.7 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 15.0.7 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 16.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 16.0.6 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 17.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 18.1.8 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 18.1.8 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 19.1.5 with MSVC-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 19.1.7 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 19.1.7 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 20.1.1 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | Clang 20.1.8 with GNU-like command-line | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | Clang 21.1.8 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | CUDA 11.0.221 (nvcc) | x86_64 | Ubuntu 20.04 LTS | GitHub | + | Emscripten 4.0.6 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 4.8.5 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 4.9.3 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 5.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 6.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 7.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 8.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 9.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 9.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 9.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 10.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 11.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 11.5.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 12.2.0 (MinGW-W64 i686-ucrt-posix-dwarf) | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | GNU 12.2.0 (MinGW-W64 x86_64-ucrt-posix-seh) | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | GNU 12.4.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 13.3.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 14.2.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 15.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 16.1.0 | x86_64 | Ubuntu 22.04.1 LTS | GitHub | + | GNU 16.1.0 | arm64 | Linux 6.1.100 | Cirrus CI | + | icpc (ICC) 2021.5.0 20211109 | x86_64 | Ubuntu 20.04.3 LTS | GitHub | + | icpx (Intel oneAPI DPC++/C++) 2025.3.2 | x86_64 | Ubuntu 24.04 LTS | GitHub | + | nvc++ (NVIDIA HPC SDK) 25.5-0 | x86_64 | Ubuntu 22.04 LTS | GitHub | + | MSVC 19.0.24241.7 | x86 | Windows 8.1 | AppVeyor | + | MSVC 19.16.27035.0 | x86 | Windows-10 (Build 14393) | AppVeyor | + | MSVC 19.29.30157.0 | x86 | Windows-10 (Build 17763) | AppVeyor | + | MSVC 19.44.35207.0 | arm64 | Windows 11 (Build 26200) | GitHub | + | MSVC 19.44.35214.0 | x86 | Windows Server 2022 (Build 20348) | GitHub | + | MSVC 19.44.35214.0 | x86_64 | Windows Server 2022 (Build 20348) | GitHub | + | MSVC 19.51.36231.0 | x86 | Windows Server 2025 (Build 26100) | GitHub | + | MSVC 19.51.36231.0 | x86_64 | Windows Server 2025 (Build 26100) | GitHub | + +- The library is compiled with all C++ language revisions (C++11, C++14, C++17, C++20, C++23, and C++26) to detect and fix language deprecations early. + +- The library is checked for compiler warnings: + +- On Clang, `-Weverything` is used with 8 exceptions. + + Clang warnings + + ``` + # Ignored Clang warnings: + # -Wno-c++98-compat The library targets C++11. + # -Wno-c++98-compat-pedantic The library targets C++11. + # -Wno-deprecated-declarations The library contains annotations for deprecated functions. + # -Wno-extra-semi-stmt The library uses assert which triggers this warning. + # -Wno-padded We do not care about padding warnings. + # -Wno-covered-switch-default All switches list all cases and a default case. + # -Wno-unsafe-buffer-usage Otherwise Doctest would not compile. + # -Wno-missing-noreturn We found no way to silence this warning otherwise, see PR #4871 + + set(CLANG_CXXFLAGS + -Werror + -Weverything + -Wno-c++98-compat + -Wno-c++98-compat-pedantic + -Wno-deprecated-declarations + -Wno-extra-semi-stmt + -Wno-padded + -Wno-covered-switch-default + -Wno-unsafe-buffer-usage + -Wno-missing-noreturn + ) + ``` + +- On GCC, 300+ warnings are enabled with 8 exceptions. + + GCC warnings + + ``` + # Warning flags determined for GCC 15.1.0 with https://github.com/nlohmann/gcc_flags: + # Ignored GCC warnings: + # -Wno-abi-tag We do not care about ABI tags. + # -Wno-aggregate-return The library uses aggregate returns. + # -Wno-long-long The library uses the long long type to interface with system functions. + # -Wno-namespaces The library uses namespaces. + # -Wno-nrvo Doctest triggers this warning. + # -Wno-padded We do not care about padding warnings. + # -Wno-system-headers We do not care about warnings in system headers. + # -Wno-templates The library uses templates. + + set(GCC_CXXFLAGS + -pedantic + -Werror + --all-warnings + --extra-warnings + -W + -WNSObject-attribute + -Wno-abi-tag + -Waddress + -Waddress-of-packed-member + -Wno-aggregate-return + -Waggressive-loop-optimizations + -Waligned-new=all + -Wall + -Walloc-size + -Walloc-zero + -Walloca + -Wanalyzer-allocation-size + -Wanalyzer-deref-before-check + -Wanalyzer-double-fclose + -Wanalyzer-double-free + -Wanalyzer-exposure-through-output-file + -Wanalyzer-exposure-through-uninit-copy + -Wanalyzer-fd-access-mode-mismatch + -Wanalyzer-fd-double-close + -Wanalyzer-fd-leak + -Wanalyzer-fd-phase-mismatch + -Wanalyzer-fd-type-mismatch + -Wanalyzer-fd-use-after-close + -Wanalyzer-fd-use-without-check + -Wanalyzer-file-leak + -Wanalyzer-free-of-non-heap + -Wanalyzer-imprecise-fp-arithmetic + -Wanalyzer-infinite-loop + -Wanalyzer-infinite-recursion + -Wanalyzer-jump-through-null + -Wanalyzer-malloc-leak + -Wanalyzer-mismatching-deallocation + -Wanalyzer-null-argument + -Wanalyzer-null-dereference + -Wanalyzer-out-of-bounds + -Wanalyzer-overlapping-buffers + -Wanalyzer-possible-null-argument + -Wanalyzer-possible-null-dereference + -Wanalyzer-putenv-of-auto-var + -Wanalyzer-shift-count-negative + -Wanalyzer-shift-count-overflow + -Wanalyzer-stale-setjmp-buffer + -Wanalyzer-symbol-too-complex + -Wanalyzer-tainted-allocation-size + -Wanalyzer-tainted-array-index + -Wanalyzer-tainted-assertion + -Wanalyzer-tainted-divisor + -Wanalyzer-tainted-offset + -Wanalyzer-tainted-size + -Wanalyzer-too-complex + -Wanalyzer-undefined-behavior-ptrdiff + -Wanalyzer-undefined-behavior-strtok + -Wanalyzer-unsafe-call-within-signal-handler + -Wanalyzer-use-after-free + -Wanalyzer-use-of-pointer-in-stale-stack-frame + -Wanalyzer-use-of-uninitialized-value + -Wanalyzer-va-arg-type-mismatch + -Wanalyzer-va-list-exhausted + -Wanalyzer-va-list-leak + -Wanalyzer-va-list-use-after-va-end + -Wanalyzer-write-to-const + -Wanalyzer-write-to-string-literal + -Warith-conversion + -Warray-bounds=2 + -Warray-compare + -Warray-parameter=2 + -Wattribute-alias=2 + -Wattribute-warning + -Wattributes + -Wbool-compare + -Wbool-operation + -Wbuiltin-declaration-mismatch + -Wbuiltin-macro-redefined + -Wc++0x-compat + -Wc++11-compat + -Wc++11-extensions + -Wc++14-compat + -Wc++14-extensions + -Wc++17-compat + -Wc++17-extensions + -Wc++1z-compat + -Wc++20-compat + -Wc++20-extensions + -Wc++23-extensions + -Wc++26-extensions + -Wc++2a-compat + -Wcalloc-transposed-args + -Wcannot-profile + -Wcast-align + -Wcast-align=strict + -Wcast-function-type + -Wcast-qual + -Wcast-user-defined + -Wcatch-value=3 + -Wchanges-meaning + -Wchar-subscripts + -Wclass-conversion + -Wclass-memaccess + -Wclobbered + -Wcomma-subscript + -Wcomment + -Wcomments + -Wcomplain-wrong-lang + -Wconditionally-supported + -Wconversion + -Wconversion-null + -Wcoverage-invalid-line-number + -Wcoverage-mismatch + -Wcoverage-too-many-conditions + -Wcoverage-too-many-paths + -Wcpp + -Wctad-maybe-unsupported + -Wctor-dtor-privacy + -Wdangling-else + -Wdangling-pointer=2 + -Wdangling-reference + -Wdate-time + -Wdefaulted-function-deleted + -Wdelete-incomplete + -Wdelete-non-virtual-dtor + -Wdeprecated + -Wdeprecated-copy + -Wdeprecated-copy-dtor + -Wdeprecated-declarations + -Wdeprecated-enum-enum-conversion + -Wdeprecated-enum-float-conversion + -Wdeprecated-literal-operator + -Wdeprecated-variadic-comma-omission + -Wdisabled-optimization + -Wdiv-by-zero + -Wdouble-promotion + -Wduplicated-branches + -Wduplicated-cond + -Weffc++ + -Welaborated-enum-base + -Wempty-body + -Wendif-labels + -Wenum-compare + -Wenum-conversion + -Wexceptions + -Wexpansion-to-defined + -Wextra + -Wextra-semi + -Wflex-array-member-not-at-end + -Wfloat-conversion + -Wfloat-equal + -Wformat -Wformat-contains-nul + -Wformat -Wformat-diag + -Wformat -Wformat-extra-args + -Wformat -Wformat-nonliteral + -Wformat -Wformat-overflow=2 + -Wformat -Wformat-security + -Wformat -Wformat-signedness + -Wformat -Wformat-truncation=2 + -Wformat -Wformat-y2k + -Wformat -Wformat-zero-length + -Wformat=2 + -Wframe-address + -Wfree-nonheap-object + -Wglobal-module + -Whardened + -Wheader-guard + -Whsa + -Wif-not-aligned + -Wignored-attributes + -Wignored-qualifiers + -Wimplicit-fallthrough=5 + -Winaccessible-base + -Winfinite-recursion + -Winherited-variadic-ctor + -Winit-list-lifetime + -Winit-self + -Winline + -Wint-in-bool-context + -Wint-to-pointer-cast + -Winterference-size + -Winvalid-constexpr + -Winvalid-imported-macros + -Winvalid-memory-model + -Winvalid-offsetof + -Winvalid-pch + -Winvalid-utf8 + -Wliteral-suffix + -Wlogical-not-parentheses + -Wlogical-op + -Wno-long-long + -Wlto-type-mismatch + -Wmain + -Wmaybe-musttail-local-addr + -Wmaybe-uninitialized + -Wmemset-elt-size + -Wmemset-transposed-args + -Wmisleading-indentation + -Wmismatched-dealloc + -Wmismatched-new-delete + -Wmismatched-tags + -Wmissing-attributes + -Wmissing-braces + -Wmissing-declarations + -Wmissing-field-initializers + -Wmissing-include-dirs + -Wmissing-profile + -Wmissing-requires + -Wmissing-template-keyword + -Wmultichar + -Wmultiple-inheritance + -Wmultistatement-macros + -Wmusttail-local-addr + -Wno-namespaces + -Wnarrowing + -Wnoexcept + -Wnoexcept-type + -Wnon-template-friend + -Wnon-virtual-dtor + -Wnonnull + -Wnonnull-compare + -Wnormalized=nfkc + -Wno-nrvo + -Wnull-dereference + -Wodr + -Wold-style-cast + -Wopenacc-parallelism + -Wopenmp + -Wopenmp-simd + -Woverflow + -Woverlength-strings + -Woverloaded-virtual=2 + -Wpacked + -Wpacked-bitfield-compat + -Wpacked-not-aligned + -Wno-padded + -Wparentheses + -Wpedantic + -Wpessimizing-move + -Wplacement-new=2 + -Wpmf-conversions + -Wpointer-arith + -Wpointer-compare + -Wpragma-once-outside-header + -Wpragmas + -Wprio-ctor-dtor + -Wpsabi + -Wrange-loop-construct + -Wredundant-decls + -Wredundant-move + -Wredundant-tags + -Wregister + -Wreorder + -Wrestrict + -Wreturn-local-addr + -Wreturn-type + -Wscalar-storage-order + -Wself-move + -Wsequence-point + -Wshadow=compatible-local + -Wshadow=global + -Wshadow=local + -Wshift-count-negative + -Wshift-count-overflow + -Wshift-negative-value + -Wshift-overflow=2 + -Wsign-compare + -Wsign-conversion + -Wsign-promo + -Wsized-deallocation + -Wsizeof-array-argument + -Wsizeof-array-div + -Wsizeof-pointer-div + -Wsizeof-pointer-memaccess + -Wstack-protector + -Wstrict-aliasing + -Wstrict-aliasing=3 + -Wstrict-null-sentinel + -Wstrict-overflow + -Wstring-compare + -Wstringop-overflow + -Wstringop-overflow=4 + -Wstringop-overread + -Wstringop-truncation + -Wsubobject-linkage + -Wsuggest-attribute=cold + -Wsuggest-attribute=const + -Wsuggest-attribute=format + -Wsuggest-attribute=malloc + -Wsuggest-attribute=noreturn + -Wsuggest-attribute=pure + -Wsuggest-attribute=returns_nonnull + -Wsuggest-final-methods + -Wsuggest-final-types + -Wsuggest-override + -Wswitch + -Wswitch-bool + -Wswitch-default + -Wswitch-enum + -Wswitch-outside-range + -Wswitch-unreachable + -Wsync-nand + -Wsynth + -Wno-system-headers + -Wtautological-compare + -Wtemplate-body + -Wtemplate-id-cdtor + -Wtemplate-names-tu-local + -Wno-templates + -Wterminate + -Wtrailing-whitespace + -Wtrampolines + -Wtrigraphs + -Wtrivial-auto-var-init + -Wtsan + -Wtype-limits + -Wundef + -Wunicode + -Wuninitialized + -Wunknown-pragmas + -Wunreachable-code + -Wunsafe-loop-optimizations + -Wunused + -Wunused-but-set-parameter + -Wunused-but-set-variable + -Wunused-const-variable=2 + -Wunused-function + -Wunused-label + -Wunused-local-typedefs + -Wunused-macros + -Wunused-parameter + -Wunused-result + -Wunused-value + -Wunused-variable + -Wuse-after-free=3 + -Wuseless-cast + -Wvarargs + -Wvariadic-macros + -Wvector-operation-performance + -Wvexing-parse + -Wvirtual-inheritance + -Wvirtual-move-assign + -Wvla + -Wvla-parameter + -Wvolatile + -Wvolatile-register-var + -Wwrite-strings + -Wxor-used-as-pow + -Wzero-as-null-pointer-constant + -Wzero-length-bounds + ) + ``` + +## C++ standard library compliance + +Requirement: No prerequisites + +The library has no prerequisites other than the Standard Template Library (STL). + +- The library is compiled and tested with both [libc++](https://libcxx.llvm.org) and [libstdc++](https://gcc.gnu.org/onlinedocs/libstdc++/) to detect subtle differences or incompatibilities. +- The code checked with [Include What You Use (IWYU)](https://include-what-you-use.org) that all required standard headers are included. +- On Windows, the library is compiled with `` being included to detect and avoid common bugs. +- The library is compiled with exceptions disabled to support alternative means of error handling. + +## Stable public API + +Requirement: Stable public API + +Any change to the library does not break the public API. + +- All public API functions are tested with a variety of arguments. +- The library is compiled and tested with different template arguments for number, string, array, and object types. +- Unit tests cover all lines of the code base. +- Every exception of the library is thrown in the test suite, and the error messages and exception ids are checked. + +Requirement: Complete documentation + +The public API is extensively documented. + +- Every public API function has a dedicated page in the [API reference documentation](https://json.nlohmann.me/api/basic_json/) with a self-contained code example. +- All examples in the documentation are tested, and changes in their output are treated as an error. + +## Robust input processing + +Requirement: Standards compliance + +The library is compliant to JSON as defined in [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259). + +- The lexer is tested with all valid Unicode code points and all prefixes of all invalid Unicode code points. +- The parser is tested against extensive correctness suites for JSON compliance. +- In addition, the library is continuously fuzz-tested at [OSS-Fuzz](https://google.github.io/oss-fuzz/) where the library is checked against billions of inputs. + +## Static analysis + +Requirement: State-of-the-art code analysis + +The code is checked with state-of-the-art static code analysis tools. + +- The code is checked with the latest [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/). + + Clang-Tidy configuration (.clang-tidy) + + ``` + # TODO: The first three checks are only removed to get the CI going. They have to be addressed at some point. + # TODO: portability-avoid-pragma-once: should be fixed eventually + + Checks: '*, + + -portability-template-virtual-member-function, + -bugprone-use-after-move, + -hicpp-invalid-access-moved, + + -altera-id-dependent-backward-branch, + -altera-struct-pack-align, + -altera-unroll-loops, + -android-cloexec-fopen, + -boost-use-ranges, + -bugprone-easily-swappable-parameters, + -cert-err58-cpp, + -clang-analyzer-webkit.NoUncountedMemberChecker, + -concurrency-mt-unsafe, + -cppcoreguidelines-avoid-const-or-ref-data-members, + -cppcoreguidelines-avoid-do-while, + -cppcoreguidelines-avoid-goto, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-non-const-global-variables, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-pro-bounds-avoid-unchecked-container-access, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-pro-bounds-constant-array-index, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-pro-type-union-access, + -cppcoreguidelines-rvalue-reference-param-not-moved, + -cppcoreguidelines-virtual-class-destructor, + -fuchsia-default-arguments-calls, + -fuchsia-default-arguments-declarations, + -fuchsia-overloaded-operator, + -google-explicit-constructor, + -google-readability-function-size, + -google-runtime-float, + -google-runtime-int, + -google-runtime-references, + -hicpp-avoid-goto, + -hicpp-explicit-conversions, + -hicpp-function-size, + -hicpp-no-array-decay, + -hicpp-no-assembler, + -hicpp-signed-bitwise, + -hicpp-uppercase-literal-suffix, + -llvm-header-guard, + -llvm-include-order, + -llvm-prefer-static-over-anonymous-namespace, + -llvm-use-ranges, + -llvmlibc-*, + -misc-use-anonymous-namespace, + -misc-confusable-identifiers, + -misc-include-cleaner, + -misc-no-recursion, + -misc-non-private-member-variables-in-classes, + -modernize-concat-nested-namespaces, + -modernize-type-traits, + -modernize-use-constraints, + -modernize-use-designated-initializers, + -modernize-use-nodiscard, + -modernize-use-ranges, + -modernize-use-std-numbers, + -modernize-use-trailing-return-type, + -performance-enum-size, + -portability-avoid-pragma-once, + -readability-function-cognitive-complexity, + -readability-function-size, + -readability-identifier-length, + -readability-magic-numbers, + -readability-redundant-access-specifiers, + -readability-redundant-parentheses, + -readability-simplify-boolean-expr, + -readability-uppercase-literal-suffix, + -readability-use-concise-preprocessor-directives' + + CheckOptions: + - key: hicpp-special-member-functions.AllowSoleDefaultDtor + value: 1 + + WarningsAsErrors: '*' + + #HeaderFilterRegex: '.*nlohmann.*' + HeaderFilterRegex: '.*hpp$' + ``` + +- The code is checked with the latest [Cppcheck](https://cppcheck.sourceforge.io) with all warnings enabled. + +- The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) with 89 enabled rules. + +- The code is checked with [Infer](https://fbinfer.com). + +- The code is checked with [Codacy](https://app.codacy.com/gh/nlohmann/json/dashboard). + +## Dynamic analysis + +Requirement: Correctness + +The library is checked for memory correctness and absence of undefined behavior. + +- The test suite is executed with enabled [runtime assertions](https://json.nlohmann.me/features/assertions/) to check invariants and preconditions of functions to detect undefined behavior. +- The test suite is executed with [Valgrind](https://valgrind.org) (Memcheck) to detect memory leaks. +- The test suite is executed with [Sanitizers](https://github.com/google/sanitizers) (address sanitizer, undefined behavior sanitizer, integer overflow detection, nullability violations). + +## Style check + +Requirement: Common code style + +A common code style is used throughout all code files of the library. + +- The code is formatted with [Artistic Style](https://astyle.sourceforge.net) (astyle) against a style configuration that is also enforced in the CI. + + Astyle configuration (tools/astyle/.astylerc) + + ``` + # Configuration for Artistic Style + # see https://astyle.sourceforge.net/astyle.html + + ####################### + # Brace Style Options # + ####################### + + # use Allman style for braces + --style=allman + + ############### + # Tab Options # + ############### + + # indent using 4 spaces + --indent=spaces=4 + + ####################### + # Indentation Options # + ####################### + + # indent access modifiers one half indent + --indent-modifiers + + # indent switch cases to the switch block + --indent-switches + + # indent preprocessor blocks + --indent-preproc-block + + # indent preprocessor defines + --indent-preproc-define + + # indent C++ comments + --indent-col1-comments + + ################### + # Padding Options # + ################### + + # insert space padding around operators + --pad-oper + + # insert space between if/for/while... and the following parentheses + --pad-header + + # attach the pointer to the variable type (left) + --align-pointer=type + + # attach the reference to the variable type (left) + --align-reference=type + + ###################### + # Formatting Options # + ###################### + + # add braces to unbraced one line conditional statements + --add-braces + + # convert tabs to spaces + --convert-tabs + + # closes whitespace between the ending angle brackets of template definitions + --close-templates + + ################# + # Other Options # + ################# + + # do not create backup files + --suffix=none + + # preserve the original file date + --preserve-date + + # display only the files that have been formatted + --formatted + + # for the linux (LF) line end style + --lineend=linux + ``` + +- The code style is checked with [cpplint](https://github.com/cpplint/cpplint) with 61 enabled rules. + +## Simple integration + +Requirement: Single header + +The library can be used by adding a single header to a C++ project. + +- An amalgamation script is used to check if the source code is exposed as a self-contained single-header file. +- The test suite is checked against the amalgamated source file as well as the individual source file. + +Requirement: CMake as primary development tool + +All library functions are exposed and usable by CMake. + +- All library options are exposed as [CMake options](https://json.nlohmann.me/integration/cmake/) and tested. +- The library is tested against relevant CMake versions: +- CMake 3.5 (the earliest supported) +- CMake 3.31.6 (the latest 3.x release) +- CMake 4.0.0 (a very recent release) diff --git a/community/security_policy.md b/community/security_policy.md new file mode 100644 index 000000000..fdee281cb --- /dev/null +++ b/community/security_policy.md @@ -0,0 +1 @@ +--8<-- "../../../.github/SECURITY.md" diff --git a/community/security_policy/index.html b/community/security_policy/index.html index 17c277f4a..081332ce8 100644 --- a/community/security_policy/index.html +++ b/community/security_policy/index.html @@ -1 +1 @@ - Security Policy - JSON for Modern C++

    Security Policy

    Reporting a Vulnerability

    We value the security of our users and appreciate your efforts to responsibly disclose vulnerabilities. If you have identified a security vulnerability in this repository, please use the GitHub Security Advisory "Report a Vulnerability" tab.

    Until it is published, this draft security advisory will only be visible to the maintainers of this project. Other users and teams may be added once the advisory is created.

    We will send a response indicating the next steps in handling your report. After the initial reply to your report, we will keep you informed of the progress towards a fix and full announcement and may ask for additional information or guidance.

    For vulnerabilities in third-party dependencies or modules, please report them directly to the respective maintainers.

    Additional Resources

    We sincerely thank you for contributing to the security and integrity of this project!

    \ No newline at end of file + Security Policy - JSON for Modern C++

    Security Policy

    Reporting a Vulnerability

    We value the security of our users and appreciate your efforts to responsibly disclose vulnerabilities. If you have identified a security vulnerability in this repository, please use the GitHub Security Advisory "Report a Vulnerability" tab.

    Until it is published, this draft security advisory will only be visible to the maintainers of this project. Other users and teams may be added once the advisory is created.

    We will send a response indicating the next steps in handling your report. After the initial reply to your report, we will keep you informed of the progress towards a fix and full announcement and may ask for additional information or guidance.

    For vulnerabilities in third-party dependencies or modules, please report them directly to the respective maintainers.

    Additional Resources

    We sincerely thank you for contributing to the security and integrity of this project!

    \ No newline at end of file diff --git a/community/security_policy/index.md b/community/security_policy/index.md new file mode 100644 index 000000000..52aa0655d --- /dev/null +++ b/community/security_policy/index.md @@ -0,0 +1,18 @@ +# Security Policy + +## Reporting a Vulnerability + +We value the security of our users and appreciate your efforts to responsibly disclose vulnerabilities. If you have identified a security vulnerability in this repository, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/nlohmann/json/security/advisories/new) tab. + +Until it is published, this draft security advisory will only be visible to the maintainers of this project. Other users and teams may be added once the advisory is created. + +We will send a response indicating the next steps in handling your report. After the initial reply to your report, we will keep you informed of the progress towards a fix and full announcement and may ask for additional information or guidance. + +For vulnerabilities in third-party dependencies or modules, please report them directly to the respective maintainers. + +## Additional Resources + +- Explore security-related topics and contribute to tools and projects through [GitHub Security Lab](https://securitylab.github.com/). +- Learn more about responsible disclosure and reporting vulnerabilities in GitHub at [About coordinated disclosure of security vulnerabilities](https://docs.github.com/en/code-security/repository-security-advisories/about-coordinated-disclosure-of-security-vulnerabilities). + +We sincerely thank you for contributing to the security and integrity of this project! diff --git a/features.md b/features.md new file mode 100644 index 000000000..0bbb2dadd --- /dev/null +++ b/features.md @@ -0,0 +1,53 @@ +# Features + +This section describes the features of the library in detail. If you are new to the library, the pages below are +roughly ordered along a typical workflow: create or parse a value, access and modify it, convert it to and from your own +C++ types, and finally serialize it again. + +## Creating and reading values + +- [Creating JSON values](creating_values.md) — build values from literals, initializer lists, and STL containers, and + understand the `#!cpp {}` vs. `#!cpp []` ambiguity. +- [Parsing](parsing/index.md) — read a JSON value from a string, file, or stream, including + [JSON Lines](parsing/json_lines.md), [callbacks](parsing/parser_callbacks.md), the + [SAX interface](parsing/sax_interface.md), and [error handling](parsing/parse_exceptions.md). +- [Comments](comments.md) and [trailing commas](trailing_commas.md) — opt-in relaxations of the JSON grammar. + +## Accessing and modifying values + +- [Element access](element_access/index.md) — unchecked ([`operator[]`](element_access/unchecked_access.md)), + checked ([`at`](element_access/checked_access.md)), and access with a + [default value](element_access/default_value.md). +- [JSON Pointer](json_pointer.md) — address values deep inside a document with [RFC 6901](https://tools.ietf.org/html/rfc6901) pointers. +- [Iterators](iterators.md) — traverse arrays and objects. +- [Modifying values](modifying_values.md) — add, update, merge, and remove elements. +- [JSON Patch and Diff](json_patch.md) and [JSON Merge Patch](merge_patch.md) — apply and compute structured changes. + +## Converting to and from C++ types + +- [Converting values](conversions.md) — get values out with [`get`](../api/basic_json/get.md)/[`get_to`](../api/basic_json/get_to.md), + and understand implicit conversions. +- [Arbitrary types conversions](arbitrary_types.md) — teach the library about your own structs and classes. +- [Specializing enum conversion](enum_conversion.md) — map enums to strings instead of integers. + +## Serializing values + +- [Serialization](serialization.md) — turn a value back into JSON text with [`dump`](../api/basic_json/dump.md), + including pretty-printing and handling of non-ASCII and invalid UTF-8. +- [Binary formats](binary_formats/index.md) — encode values more compactly as + [BJData](binary_formats/bjdata.md), [BSON](binary_formats/bson.md), [CBOR](binary_formats/cbor.md), + [MessagePack](binary_formats/messagepack.md), or [UBJSON](binary_formats/ubjson.md). +- [Binary values](binary_values.md) — store and exchange raw byte sequences. + +## How values are stored and configured + +- [Types](types/index.md) and [number handling](types/number_handling.md) — how JSON types map to C++ types and how + numbers are treated. +- [Object order](object_order.md) — keep insertion order with [`ordered_json`](../api/ordered_json.md). +- [Runtime assertions](assertions.md), [supported macros](macros.md), the [`nlohmann` namespace](namespace.md), and + [C++ modules](modules.md) — build-time and runtime configuration. + +!!! tip "Looking for a specific function?" + + This section gives conceptual overviews. For the precise signature, parameters, and return value of a function, see + the [API Documentation](../api/basic_json/index.md). diff --git a/features/arbitrary_types.md b/features/arbitrary_types.md new file mode 100644 index 000000000..949037fd1 --- /dev/null +++ b/features/arbitrary_types.md @@ -0,0 +1,327 @@ +# Arbitrary Type Conversions + +Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines: + +```cpp +namespace ns { + // a simple struct to model a person + struct person { + std::string name; + std::string address; + int age; + }; +} // namespace ns + +ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// convert to JSON: copy each value into the JSON object +json j; +j["name"] = p.name; +j["address"] = p.address; +j["age"] = p.age; + +// ... + +// convert from JSON: copy each value from the JSON object +ns::person p { + j["name"].get(), + j["address"].get(), + j["age"].get() +}; +``` + +It works, but that's quite a lot of boilerplate... Fortunately, there's a better way: + +```cpp +// create a person +ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// conversion: person -> json +json j = p; + +std::cout << j << std::endl; +// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} + +// conversion: json -> person +auto p2 = j.get(); + +// that's it +assert(p == p2); +``` + +## Basic usage + +To make this work with one of your types, you only need to provide two functions: + +```cpp +using json = nlohmann::json; + +namespace ns { + void to_json(json& j, const person& p) { + j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} }; + } + + void from_json(const json& j, person& p) { + j.at("name").get_to(p.name); + j.at("address").get_to(p.address); + j.at("age").get_to(p.age); + } +} // namespace ns +``` + +That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called. +Likewise, when calling `get()` or `get_to(your_type&)`, the `from_json` method will be called. + +Some important things: + +* Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined). +* Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [#1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise. +* When using `get()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.) +* In function `from_json`, use function [`at()`](../api/basic_json/at.md) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior. +* You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these. + + +## Simplify your life with macros + +If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate. + +There are several macros to make your life easier as long as you want to use a JSON object as serialization. The macros are following the naming pattern, and you can choose the macro based on the needed features: + +- All the macros start with `NLOHMANN_DEFINE`. +- If you want a macro for the derived object, use the [`DERIVED_TYPE`](../api/macros/nlohmann_define_derived_type.md) variant, otherwise use `TYPE`. + - The `DERIVED_TYPE` variant requires an additional parameter of a base type, which should have the `to_json`/`from_json` functions defined. For instance, with a macro of its own. +- If you need access to the private fields use [`INTRUSIVE`](../api/macros/nlohmann_define_type_intrusive.md) variant, otherwise use [`NON_INTRUSIVE`](../api/macros/nlohmann_define_type_non_intrusive.md). + - The `INTRUSIVE` macro should be defined **inside** the target class/struct, `NON_INTRUSIVE` should be defined within the same namespace. +- If you want to deserialize the incomplete JSONs, use the `WITH_DEFAULTS` variant, which will use the default values for the member variables absent in JSON, the variant without `WITH_DEFAULTS` will raise an exception. +- If you do not need deserialization at all and only interested in `to_json` function, you can use the `ONLY_SERIALIZE` variant. +- If you want to use the custom JSON names for member variables, use [`WITH_NAMES`](../api/macros/nlohmann_define_type_with_names.md) variant, otherwise the JSON name of the variable will be the same as its regular name. + +For all the macros, the first parameter is the name of the class/struct. The `DERIVED_TYPE` macros require a second parameter of a base class. All the remaining parameters name the member variables. The `WITH_NAMES` macros require a JSON name before each of the variables. + +| Need access to private members | Need only de-serialization | Allow missing values when de-serializing | macro | +|------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| +|
    :octicons-check-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    | [**NLOHMANN_DEFINE_TYPE_INTRUSIVE**](../api/macros/nlohmann_define_type_intrusive.md) | +|
    :octicons-check-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    | [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT**](../api/macros/nlohmann_define_type_intrusive.md) | +|
    :octicons-check-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    |
    :octicons-skip-fill-24:
    | [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE**](../api/macros/nlohmann_define_type_intrusive.md) | +|
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE**](../api/macros/nlohmann_define_type_non_intrusive.md) | +|
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](../api/macros/nlohmann_define_type_non_intrusive.md) | +|
    :octicons-x-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    |
    :octicons-skip-fill-24:
    | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](../api/macros/nlohmann_define_type_non_intrusive.md) | + +For _derived_ classes and structs, use the following macros + +| Need access to private members | Need only de-serialization | Allow missing values when de-serializing | macro | +|------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| +|
    :octicons-check-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    | [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE**](../api/macros/nlohmann_define_derived_type.md) | +|
    :octicons-check-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    | [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT**](../api/macros/nlohmann_define_derived_type.md) | +|
    :octicons-check-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    |
    :octicons-skip-fill-24:
    | [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE**](../api/macros/nlohmann_define_derived_type.md) | +|
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE**](../api/macros/nlohmann_define_derived_type.md) | +|
    :octicons-x-circle-fill-24:
    |
    :octicons-x-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](../api/macros/nlohmann_define_derived_type.md) | +|
    :octicons-x-circle-fill-24:
    |
    :octicons-check-circle-fill-24:
    |
    :octicons-skip-fill-24:
    | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](../api/macros/nlohmann_define_derived_type.md) | + +!!! info "Implementation limits" + + - The current macro implementations are limited to at most 63 member variables. If you want to serialize/deserialize + types with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually. + - For the `WITH_NAMES` variants the limit is halved to 31 member variables. + +??? example + + The `to_json`/`from_json` functions for the `person` struct above can be created with: + + ```cpp + namespace ns { + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age) + } + ``` + + If you want to inherit the `person` struct and add a field to it, it can be done with: + + ```cpp + namespace ns { + struct person_derived : person { + std::string email; + }; + + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(person_derived, person, email) + } + ``` + + Here is another example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed: + + ```cpp + namespace ns { + class address { + private: + std::string street; + int housenumber; + int postcode; + + public: + NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode) + }; + } + ``` + + Or in case if you use some naming convention that you do not want to expose to JSON: + + ```cpp + namespace ns { + class address { + private: + std::string m_street; + int m_housenumber; + int m_postcode; + + public: + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(address, "street", m_street, + "housenumber", m_housenumber, + "postcode", m_postcode) + }; + } + ``` + +## How do I convert third-party types? + +This requires a bit more advanced technique. But first, let us see how this conversion mechanism works: + +The library uses **JSON Serializers** to convert types to JSON. +The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)). + +It is implemented like this (simplified): + +```cpp +template +struct adl_serializer { + static void to_json(json& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + static void from_json(const json& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`... + +To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example: + +```cpp +// partial specialization (full specialization works too) +NLOHMANN_JSON_NAMESPACE_BEGIN +template +struct adl_serializer> { + static void to_json(json& j, const boost::optional& opt) { + if (opt == boost::none) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer::to_json which will + // find the free function to_json in T's namespace! + } + } + + static void from_json(const json& j, boost::optional& opt) { + if (j.is_null()) { + opt = boost::none; + } else { + opt = j.get(); // same as above, but with + // adl_serializer::from_json + } + } +}; +NLOHMANN_JSON_NAMESPACE_END +``` + +!!! note "ABI compatibility" + + Use [`NLOHMANN_JSON_NAMESPACE_BEGIN`](../api/macros/nlohmann_json_namespace_begin.md) and `NLOHMANN_JSON_NAMESPACE_END` + instead of `#!cpp namespace nlohmann { }` in code which may be linked with different versions of this library. + +## How can I use `get()` for non-default constructible/non-copyable types? + +There is a way if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload: + +```cpp +struct move_only_type { + move_only_type() = delete; + move_only_type(int ii): i(ii) {} + move_only_type(const move_only_type&) = delete; + move_only_type(move_only_type&&) = default; + + int i; +}; + +namespace nlohmann { + template <> + struct adl_serializer { + // note: the return type is no longer 'void', and the method only takes + // one argument + static move_only_type from_json(const json& j) { + return {j.get()}; + } + + // Here's the catch! You must provide a to_json method! Otherwise, you + // will not be able to convert move_only_type to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, move_only_type t) { + j = t.i; + } + }; +} +``` + +## Can I write my own serializer? (Advanced use) + +Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-udt.cpp) in the test suite, to see a few examples. + +If you write your own serializer, you will need to do a few things: + +- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`) +- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods +- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL + +Here is an example, without simplifications, that only accepts types with a size <= 32, and uses ADL. + +```cpp +// You should use void as a second template argument +// if you don't need compile-time checks on T +template::type> +struct less_than_32_serializer { + template + static void to_json(BasicJsonType& j, T value) { + // we want to use ADL, and call the correct to_json overload + using nlohmann::to_json; // this method is called by adl_serializer, + // this is where the magic happens + to_json(j, value); + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // same thing here + using nlohmann::from_json; + from_json(j, value); + } +}; +``` + +Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention: + +```cpp +template +struct bad_serializer +{ + template + static void to_json(BasicJsonType& j, const T& value) { + // this calls BasicJsonType::json_serializer::to_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + j = value; + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // this calls BasicJsonType::json_serializer::from_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + value = j.template get(); // oops! + } +}; +``` diff --git a/features/arbitrary_types/index.html b/features/arbitrary_types/index.html index 9c74d3656..2b149d257 100644 --- a/features/arbitrary_types/index.html +++ b/features/arbitrary_types/index.html @@ -179,4 +179,4 @@ value = j.template get<T>(); // oops! } }; -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/arbitrary_types/index.md b/features/arbitrary_types/index.md new file mode 100644 index 000000000..8a6163825 --- /dev/null +++ b/features/arbitrary_types/index.md @@ -0,0 +1,322 @@ +# Arbitrary Type Conversions + +Every type can be serialized in JSON, not just STL containers and scalar types. Usually, you would do something along those lines: + +``` +namespace ns { + // a simple struct to model a person + struct person { + std::string name; + std::string address; + int age; + }; +} // namespace ns + +ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// convert to JSON: copy each value into the JSON object +json j; +j["name"] = p.name; +j["address"] = p.address; +j["age"] = p.age; + +// ... + +// convert from JSON: copy each value from the JSON object +ns::person p { + j["name"].get(), + j["address"].get(), + j["age"].get() +}; +``` + +It works, but that's quite a lot of boilerplate... Fortunately, there's a better way: + +``` +// create a person +ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; + +// conversion: person -> json +json j = p; + +std::cout << j << std::endl; +// {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} + +// conversion: json -> person +auto p2 = j.get(); + +// that's it +assert(p == p2); +``` + +## Basic usage + +To make this work with one of your types, you only need to provide two functions: + +``` +using json = nlohmann::json; + +namespace ns { + void to_json(json& j, const person& p) { + j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} }; + } + + void from_json(const json& j, person& p) { + j.at("name").get_to(p.name); + j.at("address").get_to(p.address); + j.at("age").get_to(p.age); + } +} // namespace ns +``` + +That's all! When calling the `json` constructor with your type, your custom `to_json` method will be automatically called. Likewise, when calling `get()` or `get_to(your_type&)`, the `from_json` method will be called. + +Some important things: + +- Those methods **MUST** be in your type's namespace (which can be the global namespace), or the library will not be able to locate them (in this example, they are in namespace `ns`, where `person` is defined). +- Those methods **MUST** be available (e.g., proper headers must be included) everywhere you use these conversions. Look at [#1108](https://github.com/nlohmann/json/issues/1108) for errors that may occur otherwise. +- When using `get()`, `your_type` **MUST** be [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). (There is a way to bypass this requirement described later.) +- In function `from_json`, use function [`at()`](https://json.nlohmann.me/api/basic_json/at/index.md) to access the object values rather than `operator[]`. In case a key does not exist, `at` throws an exception that you can handle, whereas `operator[]` exhibits undefined behavior. +- You do not need to add serializers or deserializers for STL types like `std::vector`: the library already implements these. + +## Simplify your life with macros + +If you just want to serialize/deserialize some structs, the `to_json`/`from_json` functions can be a lot of boilerplate. + +There are several macros to make your life easier as long as you want to use a JSON object as serialization. The macros are following the naming pattern, and you can choose the macro based on the needed features: + +- All the macros start with `NLOHMANN_DEFINE`. +- If you want a macro for the derived object, use the [`DERIVED_TYPE`](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) variant, otherwise use `TYPE`. + - The `DERIVED_TYPE` variant requires an additional parameter of a base type, which should have the `to_json`/`from_json` functions defined. For instance, with a macro of its own. +- If you need access to the private fields use [`INTRUSIVE`](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) variant, otherwise use [`NON_INTRUSIVE`](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md). + - The `INTRUSIVE` macro should be defined **inside** the target class/struct, `NON_INTRUSIVE` should be defined within the same namespace. +- If you want to deserialize the incomplete JSONs, use the `WITH_DEFAULTS` variant, which will use the default values for the member variables absent in JSON, the variant without `WITH_DEFAULTS` will raise an exception. +- If you do not need deserialization at all and only interested in `to_json` function, you can use the `ONLY_SERIALIZE` variant. +- If you want to use the custom JSON names for member variables, use [`WITH_NAMES`](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) variant, otherwise the JSON name of the variable will be the same as its regular name. + +For all the macros, the first parameter is the name of the class/struct. The `DERIVED_TYPE` macros require a second parameter of a base class. All the remaining parameters name the member variables. The `WITH_NAMES` macros require a JSON name before each of the variables. + +| Need access to private members | Need only de-serialization | Allow missing values when de-serializing | macro | +| ------------------------------ | -------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| | | | [**NLOHMANN_DEFINE_TYPE_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) | +| | | | [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) | +| | | | [**NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) | +| | | | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) | +| | | | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) | +| | | | [**NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) | + +For *derived* classes and structs, use the following macros + +| Need access to private members | Need only de-serialization | Allow missing values when de-serializing | macro | +| ------------------------------ | -------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| | | | [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) | +| | | | [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) | +| | | | [**NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) | +| | | | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) | +| | | | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) | +| | | | [**NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE**](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) | + +Implementation limits + +- The current macro implementations are limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually. +- For the `WITH_NAMES` variants the limit is halved to 31 member variables. + +Example + +The `to_json`/`from_json` functions for the `person` struct above can be created with: + +``` +namespace ns { + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person, name, address, age) +} +``` + +If you want to inherit the `person` struct and add a field to it, it can be done with: + +``` +namespace ns { + struct person_derived : person { + std::string email; + }; + + NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(person_derived, person, email) +} +``` + +Here is another example with private members, where `NLOHMANN_DEFINE_TYPE_INTRUSIVE` is needed: + +``` +namespace ns { + class address { + private: + std::string street; + int housenumber; + int postcode; + + public: + NLOHMANN_DEFINE_TYPE_INTRUSIVE(address, street, housenumber, postcode) + }; +} +``` + +Or in case if you use some naming convention that you do not want to expose to JSON: + +``` +namespace ns { + class address { + private: + std::string m_street; + int m_housenumber; + int m_postcode; + + public: + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES(address, "street", m_street, + "housenumber", m_housenumber, + "postcode", m_postcode) + }; +} +``` + +## How do I convert third-party types? + +This requires a bit more advanced technique. But first, let us see how this conversion mechanism works: + +The library uses **JSON Serializers** to convert types to JSON. The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)). + +It is implemented like this (simplified): + +``` +template +struct adl_serializer { + static void to_json(json& j, const T& value) { + // calls the "to_json" method in T's namespace + } + + static void from_json(const json& j, T& value) { + // same thing, but with the "from_json" method + } +}; +``` + +This serializer works fine when you have control over the type's namespace. However, what about `boost::optional` or `std::filesystem::path` (C++17)? Hijacking the `boost` namespace is pretty bad, and it's illegal to add something other than template specializations to `std`... + +To solve this, you need to add a specialization of `adl_serializer` to the `nlohmann` namespace, here's an example: + +``` +// partial specialization (full specialization works too) +NLOHMANN_JSON_NAMESPACE_BEGIN +template +struct adl_serializer> { + static void to_json(json& j, const boost::optional& opt) { + if (opt == boost::none) { + j = nullptr; + } else { + j = *opt; // this will call adl_serializer::to_json which will + // find the free function to_json in T's namespace! + } + } + + static void from_json(const json& j, boost::optional& opt) { + if (j.is_null()) { + opt = boost::none; + } else { + opt = j.get(); // same as above, but with + // adl_serializer::from_json + } + } +}; +NLOHMANN_JSON_NAMESPACE_END +``` + +ABI compatibility + +Use [`NLOHMANN_JSON_NAMESPACE_BEGIN`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/index.md) and `NLOHMANN_JSON_NAMESPACE_END` instead of `namespace nlohmann { }` in code which may be linked with different versions of this library. + +## How can I use `get()` for non-default constructible/non-copyable types? + +There is a way if your type is [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible). You will need to specialize the `adl_serializer` as well, but with a special `from_json` overload: + +``` +struct move_only_type { + move_only_type() = delete; + move_only_type(int ii): i(ii) {} + move_only_type(const move_only_type&) = delete; + move_only_type(move_only_type&&) = default; + + int i; +}; + +namespace nlohmann { + template <> + struct adl_serializer { + // note: the return type is no longer 'void', and the method only takes + // one argument + static move_only_type from_json(const json& j) { + return {j.get()}; + } + + // Here's the catch! You must provide a to_json method! Otherwise, you + // will not be able to convert move_only_type to json, since you fully + // specialized adl_serializer on that type + static void to_json(json& j, move_only_type t) { + j = t.i; + } + }; +} +``` + +## Can I write my own serializer? (Advanced use) + +Yes. You might want to take a look at [`unit-udt.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-udt.cpp) in the test suite, to see a few examples. + +If you write your own serializer, you will need to do a few things: + +- use a different `basic_json` alias than `nlohmann::json` (the last template parameter of `basic_json` is the `JSONSerializer`) +- use your `basic_json` alias (or a template parameter) in all your `to_json`/`from_json` methods +- use `nlohmann::to_json` and `nlohmann::from_json` when you need ADL + +Here is an example, without simplifications, that only accepts types with a size \<= 32, and uses ADL. + +``` +// You should use void as a second template argument +// if you don't need compile-time checks on T +template::type> +struct less_than_32_serializer { + template + static void to_json(BasicJsonType& j, T value) { + // we want to use ADL, and call the correct to_json overload + using nlohmann::to_json; // this method is called by adl_serializer, + // this is where the magic happens + to_json(j, value); + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // same thing here + using nlohmann::from_json; + from_json(j, value); + } +}; +``` + +Be **very** careful when reimplementing your serializer, you can stack overflow if you don't pay attention: + +``` +template +struct bad_serializer +{ + template + static void to_json(BasicJsonType& j, const T& value) { + // this calls BasicJsonType::json_serializer::to_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + j = value; + } + + template + static void from_json(const BasicJsonType& j, T& value) { + // this calls BasicJsonType::json_serializer::from_json(j, value); + // if BasicJsonType::json_serializer == bad_serializer ... oops! + value = j.template get(); // oops! + } +}; +``` diff --git a/features/assertions.md b/features/assertions.md new file mode 100644 index 000000000..789af7989 --- /dev/null +++ b/features/assertions.md @@ -0,0 +1,144 @@ +# Runtime Assertions + +The code contains numerous debug assertions to ensure class invariants are valid or to detect undefined behavior. +Whereas the former class invariants are nothing to be concerned with, the latter checks for undefined behavior are to +detect bugs in client code. + +## Switch off runtime assertions + +Runtime assertions can be switched off by defining the preprocessor macro `NDEBUG` (see the +[documentation of assert](https://en.cppreference.com/w/cpp/error/assert)) which is the default for release builds. + +## Change assertion behavior + +The behavior of runtime assertions can be changed by defining macro [`JSON_ASSERT(x)`](../api/macros/json_assert.md) +before including the `json.hpp` header. + +## Function with runtime assertions + +### Unchecked object access to a const value + +Function [`operator[]`](../api/basic_json/operator%5B%5D.md) implements unchecked access for objects. Whereas a missing +key is added in the case of non-const objects, accessing a const object with a missing key is undefined behavior (think +of a dereferenced null pointer) and yields a runtime assertion. + +If you are not sure whether an element in an object exists, use checked access with the +[`at` function](../api/basic_json/at.md) or call the [`contains` function](../api/basic_json/contains.md) before. + +See also the documentation on [element access](element_access/index.md). + +??? example "Example 1: Missing object key" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + const json j = {{"key", "value"}}; + auto v = j["missing"]; + } + ``` + + Output: + + ``` + Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144. + ``` + +### Constructing from an uninitialized iterator range + +Constructing a JSON value from an iterator range (see [constructor](../api/basic_json/basic_json.md)) with an +uninitialized iterator is undefined behavior and yields a runtime assertion. + +??? example "Example 2: Uninitialized iterator range" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + json::iterator it1, it2; + json j(it1, it2); + } + ``` + + Output: + + ``` + Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368. + ``` + +### Operations on uninitialized iterators + +Any operation on uninitialized iterators (i.e., iterators that are not associated with any JSON value) is undefined +behavior and yields a runtime assertion. + +??? example "Example 3: Uninitialized iterator" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + + using json = nlohmann::json; + + int main() + { + json::iterator it; + ++it; + } + ``` + + Output: + + ``` + Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368. + ``` + +## Changes + +### Reading from a null `FILE` or `char` pointer + +Reading from a null `#!cpp FILE` or `#!cpp char` pointer in C++ is undefined behavior. Until version 3.12.0, this +library asserted that the pointer was not `nullptr` using a runtime assertion. If assertions were disabled, this would +result in undefined behavior. Since version 3.12.0, this library checks for `nullptr` and throws a +[`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) to prevent the undefined behavior. + +??? example "Example 4: Reading from null pointer" + + The following code will trigger an assertion at runtime: + + ```cpp + #include + #include + + using json = nlohmann::json; + + int main() + { + std::FILE* f = std::fopen("nonexistent_file.json", "r"); + try { + json j = json::parse(f); + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + } + } + ``` + + Output: + + ``` + [json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON + ``` + +## See also + +- [JSON_ASSERT](../api/macros/json_assert.md) - control behavior of runtime assertions diff --git a/features/assertions/index.html b/features/assertions/index.html index 3e41af296..11fdc10b3 100644 --- a/features/assertions/index.html +++ b/features/assertions/index.html @@ -43,4 +43,4 @@ } }

    Output:

    [json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON
    -

    See also

    \ No newline at end of file +

    See also

    \ No newline at end of file diff --git a/features/assertions/index.md b/features/assertions/index.md new file mode 100644 index 000000000..ec1eebc87 --- /dev/null +++ b/features/assertions/index.md @@ -0,0 +1,132 @@ +# Runtime Assertions + +The code contains numerous debug assertions to ensure class invariants are valid or to detect undefined behavior. Whereas the former class invariants are nothing to be concerned with, the latter checks for undefined behavior are to detect bugs in client code. + +## Switch off runtime assertions + +Runtime assertions can be switched off by defining the preprocessor macro `NDEBUG` (see the [documentation of assert](https://en.cppreference.com/w/cpp/error/assert)) which is the default for release builds. + +## Change assertion behavior + +The behavior of runtime assertions can be changed by defining macro [`JSON_ASSERT(x)`](https://json.nlohmann.me/api/macros/json_assert/index.md) before including the `json.hpp` header. + +## Function with runtime assertions + +### Unchecked object access to a const value + +Function [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) implements unchecked access for objects. Whereas a missing key is added in the case of non-const objects, accessing a const object with a missing key is undefined behavior (think of a dereferenced null pointer) and yields a runtime assertion. + +If you are not sure whether an element in an object exists, use checked access with the [`at` function](https://json.nlohmann.me/api/basic_json/at/index.md) or call the [`contains` function](https://json.nlohmann.me/api/basic_json/contains/index.md) before. + +See also the documentation on [element access](https://json.nlohmann.me/features/element_access/index.md). + +Example 1: Missing object key + +The following code will trigger an assertion at runtime: + +``` +#include + +using json = nlohmann::json; + +int main() +{ + const json j = {{"key", "value"}}; + auto v = j["missing"]; +} +``` + +Output: + +``` +Assertion failed: (m_value.object->find(key) != m_value.object->end()), function operator[], file json.hpp, line 2144. +``` + +### Constructing from an uninitialized iterator range + +Constructing a JSON value from an iterator range (see [constructor](https://json.nlohmann.me/api/basic_json/basic_json/index.md)) with an uninitialized iterator is undefined behavior and yields a runtime assertion. + +Example 2: Uninitialized iterator range + +The following code will trigger an assertion at runtime: + +``` +#include + +using json = nlohmann::json; + +int main() +{ + json::iterator it1, it2; + json j(it1, it2); +} +``` + +Output: + +``` +Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368. +``` + +### Operations on uninitialized iterators + +Any operation on uninitialized iterators (i.e., iterators that are not associated with any JSON value) is undefined behavior and yields a runtime assertion. + +Example 3: Uninitialized iterator + +The following code will trigger an assertion at runtime: + +``` +#include + +using json = nlohmann::json; + +int main() +{ + json::iterator it; + ++it; +} +``` + +Output: + +``` +Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368. +``` + +## Changes + +### Reading from a null `FILE` or `char` pointer + +Reading from a null `FILE` or `char` pointer in C++ is undefined behavior. Until version 3.12.0, this library asserted that the pointer was not `nullptr` using a runtime assertion. If assertions were disabled, this would result in undefined behavior. Since version 3.12.0, this library checks for `nullptr` and throws a [`parse_error.101`](https://json.nlohmann.me/home/exceptions/#jsonexceptionparse_error101) to prevent the undefined behavior. + +Example 4: Reading from null pointer + +The following code will trigger an assertion at runtime: + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::FILE* f = std::fopen("nonexistent_file.json", "r"); + try { + json j = json::parse(f); + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + } +} +``` + +Output: + +``` +[json.exception.parse_error.101] parse error: attempting to parse an empty input; check that your input string or stream contains the expected JSON +``` + +## See also + +- [JSON_ASSERT](https://json.nlohmann.me/api/macros/json_assert/index.md) - control behavior of runtime assertions diff --git a/features/binary_formats.md b/features/binary_formats.md new file mode 100644 index 000000000..ef79e2ef3 --- /dev/null +++ b/features/binary_formats.md @@ -0,0 +1,52 @@ +# Binary Formats + +Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance, over +a network. Hence, the library supports + +- [BJData](bjdata.md) (Binary JData), +- [BSON](bson.md) (Binary JSON), +- [CBOR](cbor.md) (Concise Binary Object Representation), +- [MessagePack](messagepack.md), and +- [UBJSON](ubjson.md) (Universal Binary JSON) + +to efficiently encode JSON values to byte vectors and to decode such vectors. + +## Comparison + +### Completeness + +| Format | Serialization | Deserialization | +|-------------|-----------------------------------------------|----------------------------------------------| +| BJData | complete | complete | +| BSON | incomplete: top-level value must be an object | incomplete, but all JSON types are supported | +| CBOR | complete | incomplete, but all JSON types are supported | +| MessagePack | complete | complete | +| UBJSON | complete | complete | + +### Binary values + +| Format | Binary values | Binary subtypes | +|-------------|---------------|-----------------| +| BJData | not supported | not supported | +| BSON | supported | supported | +| CBOR | supported | supported | +| MessagePack | supported | supported | +| UBJSON | not supported | not supported | + +See [binary values](../binary_values.md) for more information. + +### Sizes + +| Format | canada.json | twitter.json | citm_catalog.json | jeopardy.json | +|--------------------|-------------|--------------|-------------------|---------------| +| BJData | 53.2 % | 91.1 % | 78.1 % | 96.6 % | +| BJData (size) | 58.6 % | 92.1 % | 86.7 % | 97.4 % | +| BJData (size+type) | 58.6 % | 92.1 % | 86.5 % | 97.4 % | +| BSON | 85.8 % | 95.2 % | 95.8 % | 106.7 % | +| CBOR | 50.5 % | 86.3 % | 68.4 % | 88.0 % | +| MessagePack | 50.5 % | 86.0 % | 68.5 % | 87.9 % | +| UBJSON | 53.2 % | 91.3 % | 78.2 % | 96.6 % | +| UBJSON (size) | 58.6 % | 92.3 % | 86.8 % | 97.4 % | +| UBJSON (size+type) | 55.9 % | 92.3 % | 85.0 % | 95.0 % | + +Sizes compared to minified JSON value. diff --git a/features/binary_formats/bjdata.md b/features/binary_formats/bjdata.md new file mode 100644 index 000000000..b1b98dfe2 --- /dev/null +++ b/features/binary_formats/bjdata.md @@ -0,0 +1,206 @@ +# BJData + +The [BJData format](https://neurojson.org) was derived from and improved upon +[Universal Binary JSON(UBJSON)](https://ubjson.org) specification (Draft 12). Specifically, it introduces an optimized +array container for efficient storage of N-dimensional packed arrays (**ND-arrays**); it also adds 5 new type markers - +`[u] - uint16`, `[m] - uint32`, `[M] - uint64`, `[h] - float16` and `[B] - byte` - to unambiguously map common binary +numeric types; furthermore, it uses little-endian (LE) to store all numerics instead of big-endian (BE) as in UBJSON to +avoid unnecessary conversions on commonly available platforms. + +Compared to other binary JSON-like formats such as MessagePack and CBOR, both BJData and UBJSON demonstrate a rare +combination of being both binary and **quasi-human-readable**. This is because all semantic elements in BJData and +UBJSON, including the data-type markers and name/string types, are directly human-readable. Data stored in the +BJData/UBJSON format is not only compact in size, fast to read/write, but also can be directly searched or read using +simple processing. + +!!! abstract "References" + + - [BJData Specification](https://neurojson.org/bjdata/draft2) + +## Serialization + +The library uses the following mapping from JSON values types to BJData types according to the BJData specification: + +| JSON value type | value/range | BJData type | marker | +|-----------------|-------------------------------------------|----------------|--------| +| null | `null` | null | `Z` | +| boolean | `true` | true | `T` | +| boolean | `false` | false | `F` | +| number_integer | -9223372036854775808..-2147483649 | int64 | `L` | +| number_integer | -2147483648..-32769 | int32 | `l` | +| number_integer | -32768..-129 | int16 | `I` | +| number_integer | -128..127 | int8 | `i` | +| number_integer | 128..255 | uint8 | `U` | +| number_integer | 256..32767 | int16 | `I` | +| number_integer | 32768..65535 | uint16 | `u` | +| number_integer | 65536..2147483647 | int32 | `l` | +| number_integer | 2147483648..4294967295 | uint32 | `m` | +| number_integer | 4294967296..9223372036854775807 | int64 | `L` | +| number_integer | 9223372036854775808..18446744073709551615 | uint64 | `M` | +| number_unsigned | 0..127 | int8 | `i` | +| number_unsigned | 128..255 | uint8 | `U` | +| number_unsigned | 256..32767 | int16 | `I` | +| number_unsigned | 32768..65535 | uint16 | `u` | +| number_unsigned | 65536..2147483647 | int32 | `l` | +| number_unsigned | 2147483648..4294967295 | uint32 | `m` | +| number_unsigned | 4294967296..9223372036854775807 | int64 | `L` | +| number_unsigned | 9223372036854775808..18446744073709551615 | uint64 | `M` | +| number_float | *any value* | float64 | `D` | +| string | *with shortest length indicator* | string | `S` | +| array | *see notes on optimized format/ND-array* | array | `[` | +| object | *see notes on optimized format* | map | `{` | +| binary | *see notes on binary values* | array | `[$B` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a BJData value. + + Any BJData output created by `to_bjdata` can be successfully parsed by `from_bjdata`. + +!!! warning "Size constraints" + + The following values can **not** be converted to a BJData value: + + - strings with more than 18446744073709551615 bytes, i.e., $2^{64}-1$ bytes (theoretical) + +!!! info "Unused BJData markers" + + The following markers are not used in the conversion: + + - `Z`: no-op values are not created. + - `C`: single-byte strings are serialized with `S` markers. + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the + `dump()` function which serializes NaN or Infinity to `#!json null`. + +!!! info "Endianness" + + A breaking difference between BJData and UBJSON is the endianness of numerical values. In BJData, all numerical data + types (integers `UiuImlML` and floating-point values `hdD`) are stored in the little-endian (LE) byte order as + opposed to big-endian as used by UBJSON. Adopting LE to store numeric records avoids unnecessary byte swapping on + most modern computers where LE is used as the default byte order. + +!!! info "Optimized formats" + + Optimized formats for containers are supported via two parameters of + [`to_bjdata`](../../api/basic_json/to_bjdata.md): + + - Parameter `use_size` adds size information to the beginning of a container and removes the closing marker. + - Parameter `use_type` further checks whether all elements of a container have the same type and adds the type + marker to the beginning of the container. The `use_type` parameter must only be used together with + `use_size = true`. + + Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the + receiving side is immediately informed of the number of elements in the container. + +!!! info "ND-array optimized format" + + BJData extends UBJSON's optimized array **size** marker to support ND-arrays of uniform numerical data types + (referred to as *packed arrays*). For example, the 2-D `uint8` integer array `[[1,2],[3,4],[5,6]]`, stored as nested + optimized array in UBJSON `[ [$U#i2 1 2 [$U#i2 3 4 [$U#i2 5 6 ]`, can be further compressed in BJData to + `[$U#[$i#i2 2 3 1 2 3 4 5 6` or `[$U#[i2 i3] 1 2 3 4 5 6`. + + To maintain type and size information, ND-arrays are converted to JSON objects following the **annotated array + format** (defined in the [JData specification (Draft 3)][JDataAAFmt]), when parsed using + [`from_bjdata`](../../api/basic_json/from_bjdata.md). For example, the above 2-D `uint8` array can be parsed and + accessed as + + ```json + { + "_ArrayType_": "uint8", + "_ArraySize_": [2,3], + "_ArrayData_": [1,2,3,4,5,6] + } + ``` + + Likewise, when a JSON object in the above form is serialized using + [`to_bjdata`](../../api/basic_json/to_bjdata.md), it is automatically converted into a compact BJData ND-array. The + only exception is, that when the 1-dimensional vector stored in `"_ArraySize_"` contains a single integer or two + integers with one being 1, a regular 1-D optimized array is generated. + + The current version of this library does not yet support automatic detection of and conversion from a nested JSON + array input to a BJData ND-array. + + [JDataAAFmt]: https://github.com/NeuroJSON/jdata/blob/master/JData_specification.md#annotated-storage-of-n-d-arrays + +!!! info "Restrictions in optimized data types for arrays and objects" + + Due to diminished space saving, hampered readability, and increased security risks, in BJData, the allowed data + types following the `$` marker in an optimized array and object container are restricted to + **non-zero-fixed-length** data types. Therefore, the valid optimized type markers can only be one of + `UiuImlMLhdDCB`. This also means other variable (`[{SH`) or zero-length types (`TFN`) can not be used in an + optimized array or object in BJData. + +!!! info "Binary values" + + BJData provides a dedicated `B` marker (defined in the [BJData specification (Draft 3)][BJDataBinArr]) that is used + in optimized arrays to designate binary data. This means that, unlike UBJSON, binary data can be both serialized and + deserialized. + + To preserve compatibility with BJData Draft 2, the Draft 3 optimized binary array must be explicitly enabled using + the `version` parameter of [`to_bjdata`](../../api/basic_json/to_bjdata.md). + + In Draft2 mode (default), if the JSON data contains the binary type, the value stored as a list of integers, as + suggested by the BJData documentation. In particular, this means that the serialization and the deserialization of + JSON containing binary values into BJData and back will result in a different JSON object. + + [BJDataBinArr]: https://github.com/NeuroJSON/bjdata/blob/master/Binary_JData_Specification.md#optimized-binary-array + +??? example + + ```cpp + --8<-- "examples/to_bjdata.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_bjdata.output" + ``` + +## Deserialization + +The library maps BJData types to JSON value types as follows: + +| BJData type | JSON value type | marker | +|-------------|------------------------------------------|----------| +| no-op | *no value, next value is read* | `N` | +| null | `null` | `Z` | +| false | `false` | `F` | +| true | `true` | `T` | +| float16 | number_float | `h` | +| float32 | number_float | `d` | +| float64 | number_float | `D` | +| uint8 | number_unsigned | `U` | +| int8 | number_integer | `i` | +| uint16 | number_unsigned | `u` | +| int16 | number_integer | `I` | +| uint32 | number_unsigned | `m` | +| int32 | number_integer | `l` | +| uint64 | number_unsigned | `M` | +| int64 | number_integer | `L` | +| byte | number_unsigned | `B` | +| string | string | `S` | +| char | string | `C` | +| array | array (optimized values are supported) | `[` | +| ND-array | object (in JData annotated array format) | `[$.#[.` | +| object | object (optimized values are supported) | `{` | +| binary | binary (strongly-typed byte array) | `[$B` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any BJData value can be converted to a JSON value. + +??? example + + ```cpp + --8<-- "examples/from_bjdata.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bjdata.output" + ``` diff --git a/features/binary_formats/bjdata/index.html b/features/binary_formats/bjdata/index.html index a635f616e..294fd8622 100644 --- a/features/binary_formats/bjdata/index.html +++ b/features/binary_formats/bjdata/index.html @@ -95,4 +95,4 @@ "compact": true, "schema": 0 } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/binary_formats/bjdata/index.md b/features/binary_formats/bjdata/index.md new file mode 100644 index 000000000..5a942ab85 --- /dev/null +++ b/features/binary_formats/bjdata/index.md @@ -0,0 +1,254 @@ +# BJData + +The [BJData format](https://neurojson.org) was derived from and improved upon [Universal Binary JSON(UBJSON)](https://ubjson.org) specification (Draft 12). Specifically, it introduces an optimized array container for efficient storage of N-dimensional packed arrays (**ND-arrays**); it also adds 5 new type markers - `[u] - uint16`, `[m] - uint32`, `[M] - uint64`, `[h] - float16` and `[B] - byte` - to unambiguously map common binary numeric types; furthermore, it uses little-endian (LE) to store all numerics instead of big-endian (BE) as in UBJSON to avoid unnecessary conversions on commonly available platforms. + +Compared to other binary JSON-like formats such as MessagePack and CBOR, both BJData and UBJSON demonstrate a rare combination of being both binary and **quasi-human-readable**. This is because all semantic elements in BJData and UBJSON, including the data-type markers and name/string types, are directly human-readable. Data stored in the BJData/UBJSON format is not only compact in size, fast to read/write, but also can be directly searched or read using simple processing. + +References + +- [BJData Specification](https://neurojson.org/bjdata/draft2) + +## Serialization + +The library uses the following mapping from JSON values types to BJData types according to the BJData specification: + +| JSON value type | value/range | BJData type | marker | +| --------------- | ----------------------------------------- | ----------- | ------ | +| null | `null` | null | `Z` | +| boolean | `true` | true | `T` | +| boolean | `false` | false | `F` | +| number_integer | -9223372036854775808..-2147483649 | int64 | `L` | +| number_integer | -2147483648..-32769 | int32 | `l` | +| number_integer | -32768..-129 | int16 | `I` | +| number_integer | -128..127 | int8 | `i` | +| number_integer | 128..255 | uint8 | `U` | +| number_integer | 256..32767 | int16 | `I` | +| number_integer | 32768..65535 | uint16 | `u` | +| number_integer | 65536..2147483647 | int32 | `l` | +| number_integer | 2147483648..4294967295 | uint32 | `m` | +| number_integer | 4294967296..9223372036854775807 | int64 | `L` | +| number_integer | 9223372036854775808..18446744073709551615 | uint64 | `M` | +| number_unsigned | 0..127 | int8 | `i` | +| number_unsigned | 128..255 | uint8 | `U` | +| number_unsigned | 256..32767 | int16 | `I` | +| number_unsigned | 32768..65535 | uint16 | `u` | +| number_unsigned | 65536..2147483647 | int32 | `l` | +| number_unsigned | 2147483648..4294967295 | uint32 | `m` | +| number_unsigned | 4294967296..9223372036854775807 | int64 | `L` | +| number_unsigned | 9223372036854775808..18446744073709551615 | uint64 | `M` | +| number_float | *any value* | float64 | `D` | +| string | *with shortest length indicator* | string | `S` | +| array | *see notes on optimized format/ND-array* | array | `[` | +| object | *see notes on optimized format* | map | `{` | +| binary | *see notes on binary values* | array | `[$B` | + +Complete mapping + +The mapping is **complete** in the sense that any JSON value type can be converted to a BJData value. + +Any BJData output created by `to_bjdata` can be successfully parsed by `from_bjdata`. + +Size constraints + +The following values can **not** be converted to a BJData value: + +- strings with more than 18446744073709551615 bytes, i.e., 2^{64}-1 bytes (theoretical) + +Unused BJData markers + +The following markers are not used in the conversion: + +- `Z`: no-op values are not created. +- `C`: single-byte strings are serialized with `S` markers. + +NaN/infinity handling + +If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the `dump()` function which serializes NaN or Infinity to `null`. + +Endianness + +A breaking difference between BJData and UBJSON is the endianness of numerical values. In BJData, all numerical data types (integers `UiuImlML` and floating-point values `hdD`) are stored in the little-endian (LE) byte order as opposed to big-endian as used by UBJSON. Adopting LE to store numeric records avoids unnecessary byte swapping on most modern computers where LE is used as the default byte order. + +Optimized formats + +Optimized formats for containers are supported via two parameters of [`to_bjdata`](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md): + +- Parameter `use_size` adds size information to the beginning of a container and removes the closing marker. +- Parameter `use_type` further checks whether all elements of a container have the same type and adds the type marker to the beginning of the container. The `use_type` parameter must only be used together with `use_size = true`. + +Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the receiving side is immediately informed of the number of elements in the container. + +ND-array optimized format + +BJData extends UBJSON's optimized array **size** marker to support ND-arrays of uniform numerical data types (referred to as *packed arrays*). For example, the 2-D `uint8` integer array `[[1,2],[3,4],[5,6]]`, stored as nested optimized array in UBJSON `[ [$U#i2 1 2 [$U#i2 3 4 [$U#i2 5 6 ]`, can be further compressed in BJData to `[$U#[$i#i2 2 3 1 2 3 4 5 6` or `[$U#[i2 i3] 1 2 3 4 5 6`. + +To maintain type and size information, ND-arrays are converted to JSON objects following the **annotated array format** (defined in the [JData specification (Draft 3)](https://github.com/NeuroJSON/jdata/blob/master/JData_specification.md#annotated-storage-of-n-d-arrays)), when parsed using [`from_bjdata`](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md). For example, the above 2-D `uint8` array can be parsed and accessed as + +``` +{ + "_ArrayType_": "uint8", + "_ArraySize_": [2,3], + "_ArrayData_": [1,2,3,4,5,6] +} +``` + +Likewise, when a JSON object in the above form is serialized using [`to_bjdata`](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md), it is automatically converted into a compact BJData ND-array. The only exception is, that when the 1-dimensional vector stored in `"_ArraySize_"` contains a single integer or two integers with one being 1, a regular 1-D optimized array is generated. + +The current version of this library does not yet support automatic detection of and conversion from a nested JSON array input to a BJData ND-array. + +Restrictions in optimized data types for arrays and objects + +Due to diminished space saving, hampered readability, and increased security risks, in BJData, the allowed data types following the `$` marker in an optimized array and object container are restricted to **non-zero-fixed-length** data types. Therefore, the valid optimized type markers can only be one of `UiuImlMLhdDCB`. This also means other variable (`[{SH`) or zero-length types (`TFN`) can not be used in an optimized array or object in BJData. + +Binary values + +BJData provides a dedicated `B` marker (defined in the [BJData specification (Draft 3)](https://github.com/NeuroJSON/bjdata/blob/master/Binary_JData_Specification.md#optimized-binary-array)) that is used in optimized arrays to designate binary data. This means that, unlike UBJSON, binary data can be both serialized and deserialized. + +To preserve compatibility with BJData Draft 2, the Draft 3 optimized binary array must be explicitly enabled using the `version` parameter of [`to_bjdata`](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md). + +In Draft2 mode (default), if the JSON data contains the binary type, the value stored as a list of integers, as suggested by the BJData documentation. In particular, this means that the serialization and the deserialization of JSON containing binary values into BJData and back will result in a different JSON object. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +// function to print BJData's diagnostic format +void print_byte(uint8_t byte) +{ + if (32 < byte and byte < 128) + { + std::cout << (char)byte; + } + else + { + std::cout << (int)byte; + } +} + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": false})"_json; + + // serialize it to BJData + std::vector v = json::to_bjdata(j); + + // print the vector content + for (auto& byte : v) + { + print_byte(byte); + } + std::cout << std::endl; + + // create an array of numbers + json array = {1, 2, 3, 4, 5, 6, 7, 8}; + + // serialize it to BJData using default representation + std::vector v_array = json::to_bjdata(array); + // serialize it to BJData using size optimization + std::vector v_array_size = json::to_bjdata(array, true); + // serialize it to BJData using type optimization + std::vector v_array_size_and_type = json::to_bjdata(array, true, true); + + // print the vector contents + for (auto& byte : v_array) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size_and_type) + { + print_byte(byte); + } + std::cout << std::endl; +} +``` + +Output: + +``` +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 +``` + +## Deserialization + +The library maps BJData types to JSON value types as follows: + +| BJData type | JSON value type | marker | +| ----------- | ---------------------------------------- | -------- | +| no-op | *no value, next value is read* | `N` | +| null | `null` | `Z` | +| false | `false` | `F` | +| true | `true` | `T` | +| float16 | number_float | `h` | +| float32 | number_float | `d` | +| float64 | number_float | `D` | +| uint8 | number_unsigned | `U` | +| int8 | number_integer | `i` | +| uint16 | number_unsigned | `u` | +| int16 | number_integer | `I` | +| uint32 | number_unsigned | `m` | +| int32 | number_integer | `l` | +| uint64 | number_unsigned | `M` | +| int64 | number_integer | `L` | +| byte | number_unsigned | `B` | +| string | string | `S` | +| char | string | `C` | +| array | array (optimized values are supported) | `[` | +| ND-array | object (in JData annotated array format) | `[$.#[.` | +| object | object (optimized values are supported) | `{` | +| binary | binary (strongly-typed byte array) | `[$B` | + +Complete mapping + +The mapping is **complete** in the sense that any BJData value can be converted to a JSON value. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, + 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D + }; + + // deserialize it with BJData + json j = json::from_bjdata(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` diff --git a/features/binary_formats/bson.md b/features/binary_formats/bson.md new file mode 100644 index 000000000..9b7685131 --- /dev/null +++ b/features/binary_formats/bson.md @@ -0,0 +1,98 @@ +# BSON + +BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the +embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow +representation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type. + +!!! abstract "References" + + - [BSON Website](http://bsonspec.org) - the main source on BSON + - [BSON Specification](http://bsonspec.org/spec.html) - the specification + + +## Serialization + +The library uses the following mapping from JSON values types to BSON types: + +| JSON value type | value/range | BSON type | marker | +|-----------------|-------------------------------------------|-----------|--------| +| null | `null` | null | 0x0A | +| boolean | `true`, `false` | boolean | 0x08 | +| number_integer | -9223372036854775808..-2147483649 | int64 | 0x12 | +| number_integer | -2147483648..2147483647 | int32 | 0x10 | +| number_integer | 2147483648..9223372036854775807 | int64 | 0x12 | +| number_unsigned | 0..2147483647 | int32 | 0x10 | +| number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 | +| number_unsigned | 9223372036854775808..18446744073709551615 | uint64 | 0x11 | +| number_float | *any value* | double | 0x01 | +| string | *any value* | string | 0x02 | +| array | *any value* | document | 0x04 | +| object | *any value* | document | 0x03 | +| binary | *any value* | binary | 0x05 | + +!!! warning "Incomplete mapping" + + The mapping is **incomplete**, since only JSON-objects (and things contained therein) can be serialized to BSON. + Also, keys may not contain U+0000, since they are serialized a zero-terminated c-strings. + +??? example + + ```cpp + --8<-- "examples/to_bson.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_bson.output" + ``` + + +## Deserialization + +The library maps BSON record types to JSON value types as follows: + +| BSON type | BSON marker byte | JSON value type | +|--------------------------|------------------|-----------------| +| double | 0x01 | number_float | +| string | 0x02 | string | +| document | 0x03 | object | +| array | 0x04 | array | +| binary | 0x05 | binary | +| undefined | 0x06 | *unsupported* | +| ObjectId | 0x07 | *unsupported* | +| boolean | 0x08 | boolean | +| UTC Date-Time | 0x09 | *unsupported* | +| null | 0x0A | null | +| Regular Expr. | 0x0B | *unsupported* | +| DB Pointer | 0x0C | *unsupported* | +| JavaScript Code | 0x0D | *unsupported* | +| Symbol | 0x0E | *unsupported* | +| JavaScript Code w/ scope | 0x0F | *unsupported* | +| int32 | 0x10 | number_integer | +| uint64(Timestamp) | 0x11 | number_unsigned | +| int64 | 0x12 | number_integer | +| 128-bit decimal float | 0x13 | *unsupported* | +| Max Key | 0x7F | *unsupported* | +| Min Key | 0xFF | *unsupported* | + +!!! warning "Incomplete mapping" + + The mapping is **incomplete**. The unsupported mappings are indicated in the table above. + +!!! note "Handling of BSON type 0x11" + + BSON type 0x11 is used to represent uint64 numbers. This library treats these values purely as uint64 numbers + and does not parse them into date-related formats. + +??? example + + ```cpp + --8<-- "examples/from_bson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_bson.output" + ``` diff --git a/features/binary_formats/bson/index.html b/features/binary_formats/bson/index.html index 08107736d..a86b31ec7 100644 --- a/features/binary_formats/bson/index.html +++ b/features/binary_formats/bson/index.html @@ -46,4 +46,4 @@ "compact": true, "schema": 0 } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/binary_formats/bson/index.md b/features/binary_formats/bson/index.md new file mode 100644 index 000000000..55f676bae --- /dev/null +++ b/features/binary_formats/bson/index.md @@ -0,0 +1,136 @@ +# BSON + +BSON, short for Binary JSON, is a binary-encoded serialization of JSON-like documents. Like JSON, BSON supports the embedding of documents and arrays within other documents and arrays. BSON also contains extensions that allow representation of data types that are not part of the JSON spec. For example, BSON has a Date type and a BinData type. + +References + +- [BSON Website](http://bsonspec.org) - the main source on BSON +- [BSON Specification](http://bsonspec.org/spec.html) - the specification + +## Serialization + +The library uses the following mapping from JSON values types to BSON types: + +| JSON value type | value/range | BSON type | marker | +| --------------- | ----------------------------------------- | --------- | ------ | +| null | `null` | null | 0x0A | +| boolean | `true`, `false` | boolean | 0x08 | +| number_integer | -9223372036854775808..-2147483649 | int64 | 0x12 | +| number_integer | -2147483648..2147483647 | int32 | 0x10 | +| number_integer | 2147483648..9223372036854775807 | int64 | 0x12 | +| number_unsigned | 0..2147483647 | int32 | 0x10 | +| number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12 | +| number_unsigned | 9223372036854775808..18446744073709551615 | uint64 | 0x11 | +| number_float | *any value* | double | 0x01 | +| string | *any value* | string | 0x02 | +| array | *any value* | document | 0x04 | +| object | *any value* | document | 0x03 | +| binary | *any value* | binary | 0x05 | + +Incomplete mapping + +The mapping is **incomplete**, since only JSON-objects (and things contained therein) can be serialized to BSON. Also, keys may not contain U+0000, since they are serialized a zero-terminated c-strings. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to BSON + std::vector v = json::to_bson(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} +``` + +Output: + +``` +0x1b 0x00 0x00 0x00 0x08 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0x00 0x01 0x10 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 0x00 0x00 0x00 0x00 0x00 +``` + +## Deserialization + +The library maps BSON record types to JSON value types as follows: + +| BSON type | BSON marker byte | JSON value type | +| ------------------------ | ---------------- | --------------- | +| double | 0x01 | number_float | +| string | 0x02 | string | +| document | 0x03 | object | +| array | 0x04 | array | +| binary | 0x05 | binary | +| undefined | 0x06 | *unsupported* | +| ObjectId | 0x07 | *unsupported* | +| boolean | 0x08 | boolean | +| UTC Date-Time | 0x09 | *unsupported* | +| null | 0x0A | null | +| Regular Expr. | 0x0B | *unsupported* | +| DB Pointer | 0x0C | *unsupported* | +| JavaScript Code | 0x0D | *unsupported* | +| Symbol | 0x0E | *unsupported* | +| JavaScript Code w/ scope | 0x0F | *unsupported* | +| int32 | 0x10 | number_integer | +| uint64(Timestamp) | 0x11 | number_unsigned | +| int64 | 0x12 | number_integer | +| 128-bit decimal float | 0x13 | *unsupported* | +| Max Key | 0x7F | *unsupported* | +| Min Key | 0xFF | *unsupported* | + +Incomplete mapping + +The mapping is **incomplete**. The unsupported mappings are indicated in the table above. + +Handling of BSON type 0x11 + +BSON type 0x11 is used to represent uint64 numbers. This library treats these values purely as uint64 numbers and does not parse them into date-related formats. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x1b, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 + }; + + // deserialize it with BSON + json j = json::from_bson(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` diff --git a/features/binary_formats/cbor.md b/features/binary_formats/cbor.md new file mode 100644 index 000000000..1bd28c8da --- /dev/null +++ b/features/binary_formats/cbor.md @@ -0,0 +1,181 @@ +# CBOR + +The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of +extremely small code sizes, fairly small message size, and extensibility without the need for version negotiation. + +!!! abstract "References" + + - [CBOR Website](http://cbor.io) - the main source on CBOR + - [CBOR Playground](http://cbor.me) - an interactive webpage to translate between JSON and CBOR + - [RFC 7049](https://tools.ietf.org/html/rfc7049) - the CBOR specification + +## Serialization + +The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification +([RFC 7049](https://www.rfc-editor.org/rfc/rfc7049.html)): + +| JSON value type | value/range | CBOR type | first byte | +|-----------------|--------------------------------------------|-----------------------------------|------------| +| null | `null` | Null | 0xF6 | +| boolean | `true` | True | 0xF5 | +| boolean | `false` | False | 0xF4 | +| number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B | +| number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A | +| number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 | +| number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 | +| number_integer | -24..-1 | Negative integer | 0x20..0x37 | +| number_integer | 0..23 | Integer | 0x00..0x17 | +| number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 | +| number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 | +| number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A | +| number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B | +| number_unsigned | 0..23 | Integer | 0x00..0x17 | +| number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 | +| number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 | +| number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A | +| number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B | +| number_float | *any value representable by a float* | Single-Precision Float | 0xFA | +| number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB | +| string | *length*: 0..23 | UTF-8 string | 0x60..0x77 | +| string | *length*: 24..255 | UTF-8 string (1 byte follow) | 0x78 | +| string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79 | +| string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A | +| string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B | +| array | *size*: 0..23 | array | 0x80..0x97 | +| array | *size*: 24..255 | array (1 byte follow) | 0x98 | +| array | *size*: 256..65535 | array (2 bytes follow) | 0x99 | +| array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A | +| array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B | +| object | *size*: 0..23 | map | 0xA0..0xB7 | +| object | *size*: 24..255 | map (1 byte follow) | 0xB8 | +| object | *size*: 256..65535 | map (2 bytes follow) | 0xB9 | +| object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA | +| object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB | +| binary | *size*: 0..23 | byte string | 0x40..0x57 | +| binary | *size*: 24..255 | byte string (1 byte follow) | 0x58 | +| binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59 | +| binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A | +| binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B | + +Binary values with subtype are mapped to tagged values (0xD8..0xDB) depending on the subtype, followed by a byte string, +see "binary" cells in the table above. + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a CBOR value. + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to `null`. + +!!! info "Unused CBOR types" + + The following CBOR types are not used in the conversion: + + - UTF-8 strings terminated by "break" (0x7F) + - arrays terminated by "break" (0x9F) + - maps terminated by "break" (0xBF) + - byte strings terminated by "break" (0x5F) + - date/time (0xC0..0xC1) + - bignum (0xC2..0xC3) + - decimal fraction (0xC4) + - bigfloat (0xC5) + - expected conversions (0xD5..0xD7) + - simple values (0xE0..0xF3, 0xF8) + - undefined (0xF7) + - half-precision floats (0xF9) + - break (0xFF) + +!!! info "Tagged items" + + Binary subtypes will be serialized as tagged items. See [binary values](../binary_values.md#cbor) for an example. + +??? example + + ```cpp + --8<-- "examples/to_cbor.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_cbor.output" + ``` + +## Deserialization + +The library maps CBOR types to JSON value types as follows: + +| CBOR type | JSON value type | first byte | +|------------------------|-----------------|------------| +| Integer | number_unsigned | 0x00..0x17 | +| Unsigned integer | number_unsigned | 0x18 | +| Unsigned integer | number_unsigned | 0x19 | +| Unsigned integer | number_unsigned | 0x1A | +| Unsigned integer | number_unsigned | 0x1B | +| Negative integer | number_integer | 0x20..0x37 | +| Negative integer | number_integer | 0x38 | +| Negative integer | number_integer | 0x39 | +| Negative integer | number_integer | 0x3A | +| Negative integer | number_integer | 0x3B | +| Byte string | binary | 0x40..0x57 | +| Byte string | binary | 0x58 | +| Byte string | binary | 0x59 | +| Byte string | binary | 0x5A | +| Byte string | binary | 0x5B | +| UTF-8 string | string | 0x60..0x77 | +| UTF-8 string | string | 0x78 | +| UTF-8 string | string | 0x79 | +| UTF-8 string | string | 0x7A | +| UTF-8 string | string | 0x7B | +| UTF-8 string | string | 0x7F | +| array | array | 0x80..0x97 | +| array | array | 0x98 | +| array | array | 0x99 | +| array | array | 0x9A | +| array | array | 0x9B | +| array | array | 0x9F | +| map | object | 0xA0..0xB7 | +| map | object | 0xB8 | +| map | object | 0xB9 | +| map | object | 0xBA | +| map | object | 0xBB | +| map | object | 0xBF | +| False | `false` | 0xF4 | +| True | `true` | 0xF5 | +| Null | `null` | 0xF6 | +| Half-Precision Float | number_float | 0xF9 | +| Single-Precision Float | number_float | 0xFA | +| Double-Precision Float | number_float | 0xFB | + +!!! warning "Incomplete mapping" + + The mapping is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors: + + - date/time (0xC0..0xC1) + - bignum (0xC2..0xC3) + - decimal fraction (0xC4) + - bigfloat (0xC5) + - expected conversions (0xD5..0xD7) + - simple values (0xE0..0xF3, 0xF8) + - undefined (0xF7) + +!!! warning "Object keys" + + CBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than UTF-8 strings are rejected. + +!!! warning "Tagged items" + + Tagged items will throw a parse error by default. They can be ignored by passing `cbor_tag_handler_t::ignore` to function `from_cbor`. They can be stored by passing `cbor_tag_handler_t::store` to function `from_cbor`. + +??? example + + ```cpp + --8<-- "examples/from_cbor.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_cbor.output" + ``` diff --git a/features/binary_formats/cbor/index.html b/features/binary_formats/cbor/index.html index d73481f55..ddf7537dc 100644 --- a/features/binary_formats/cbor/index.html +++ b/features/binary_formats/cbor/index.html @@ -45,4 +45,4 @@ "compact": true, "schema": 0 } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/binary_formats/cbor/index.md b/features/binary_formats/cbor/index.md new file mode 100644 index 000000000..3c2e4b0ad --- /dev/null +++ b/features/binary_formats/cbor/index.md @@ -0,0 +1,221 @@ +# CBOR + +The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code sizes, fairly small message size, and extensibility without the need for version negotiation. + +References + +- [CBOR Website](http://cbor.io) - the main source on CBOR +- [CBOR Playground](http://cbor.me) - an interactive webpage to translate between JSON and CBOR +- [RFC 7049](https://tools.ietf.org/html/rfc7049) - the CBOR specification + +## Serialization + +The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification ([RFC 7049](https://www.rfc-editor.org/rfc/rfc7049.html)): + +| JSON value type | value/range | CBOR type | first byte | +| --------------- | ------------------------------------------ | --------------------------------- | ---------- | +| null | `null` | Null | 0xF6 | +| boolean | `true` | True | 0xF5 | +| boolean | `false` | False | 0xF4 | +| number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B | +| number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A | +| number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39 | +| number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38 | +| number_integer | -24..-1 | Negative integer | 0x20..0x37 | +| number_integer | 0..23 | Integer | 0x00..0x17 | +| number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18 | +| number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 | +| number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A | +| number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B | +| number_unsigned | 0..23 | Integer | 0x00..0x17 | +| number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18 | +| number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19 | +| number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A | +| number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B | +| number_float | *any value representable by a float* | Single-Precision Float | 0xFA | +| number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB | +| string | *length*: 0..23 | UTF-8 string | 0x60..0x77 | +| string | *length*: 24..255 | UTF-8 string (1 byte follow) | 0x78 | +| string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79 | +| string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A | +| string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B | +| array | *size*: 0..23 | array | 0x80..0x97 | +| array | *size*: 24..255 | array (1 byte follow) | 0x98 | +| array | *size*: 256..65535 | array (2 bytes follow) | 0x99 | +| array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A | +| array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B | +| object | *size*: 0..23 | map | 0xA0..0xB7 | +| object | *size*: 24..255 | map (1 byte follow) | 0xB8 | +| object | *size*: 256..65535 | map (2 bytes follow) | 0xB9 | +| object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA | +| object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB | +| binary | *size*: 0..23 | byte string | 0x40..0x57 | +| binary | *size*: 24..255 | byte string (1 byte follow) | 0x58 | +| binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59 | +| binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A | +| binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B | + +Binary values with subtype are mapped to tagged values (0xD8..0xDB) depending on the subtype, followed by a byte string, see "binary" cells in the table above. + +Complete mapping + +The mapping is **complete** in the sense that any JSON value type can be converted to a CBOR value. + +NaN/infinity handling + +If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the normal JSON serialization which serializes NaN or Infinity to `null`. + +Unused CBOR types + +The following CBOR types are not used in the conversion: + +- UTF-8 strings terminated by "break" (0x7F) +- arrays terminated by "break" (0x9F) +- maps terminated by "break" (0xBF) +- byte strings terminated by "break" (0x5F) +- date/time (0xC0..0xC1) +- bignum (0xC2..0xC3) +- decimal fraction (0xC4) +- bigfloat (0xC5) +- expected conversions (0xD5..0xD7) +- simple values (0xE0..0xF3, 0xF8) +- undefined (0xF7) +- half-precision floats (0xF9) +- break (0xFF) + +Tagged items + +Binary subtypes will be serialized as tagged items. See [binary values](https://json.nlohmann.me/features/binary_values/#cbor) for an example. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to CBOR + std::vector v = json::to_cbor(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} +``` + +Output: + +``` +0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 +``` + +## Deserialization + +The library maps CBOR types to JSON value types as follows: + +| CBOR type | JSON value type | first byte | +| ---------------------- | --------------- | ---------- | +| Integer | number_unsigned | 0x00..0x17 | +| Unsigned integer | number_unsigned | 0x18 | +| Unsigned integer | number_unsigned | 0x19 | +| Unsigned integer | number_unsigned | 0x1A | +| Unsigned integer | number_unsigned | 0x1B | +| Negative integer | number_integer | 0x20..0x37 | +| Negative integer | number_integer | 0x38 | +| Negative integer | number_integer | 0x39 | +| Negative integer | number_integer | 0x3A | +| Negative integer | number_integer | 0x3B | +| Byte string | binary | 0x40..0x57 | +| Byte string | binary | 0x58 | +| Byte string | binary | 0x59 | +| Byte string | binary | 0x5A | +| Byte string | binary | 0x5B | +| UTF-8 string | string | 0x60..0x77 | +| UTF-8 string | string | 0x78 | +| UTF-8 string | string | 0x79 | +| UTF-8 string | string | 0x7A | +| UTF-8 string | string | 0x7B | +| UTF-8 string | string | 0x7F | +| array | array | 0x80..0x97 | +| array | array | 0x98 | +| array | array | 0x99 | +| array | array | 0x9A | +| array | array | 0x9B | +| array | array | 0x9F | +| map | object | 0xA0..0xB7 | +| map | object | 0xB8 | +| map | object | 0xB9 | +| map | object | 0xBA | +| map | object | 0xBB | +| map | object | 0xBF | +| False | `false` | 0xF4 | +| True | `true` | 0xF5 | +| Null | `null` | 0xF6 | +| Half-Precision Float | number_float | 0xF9 | +| Single-Precision Float | number_float | 0xFA | +| Double-Precision Float | number_float | 0xFB | + +Incomplete mapping + +The mapping is **incomplete** in the sense that not all CBOR types can be converted to a JSON value. The following CBOR types are not supported and will yield parse errors: + +- date/time (0xC0..0xC1) +- bignum (0xC2..0xC3) +- decimal fraction (0xC4) +- bigfloat (0xC5) +- expected conversions (0xD5..0xD7) +- simple values (0xE0..0xF3, 0xF8) +- undefined (0xF7) + +Object keys + +CBOR allows map keys of any type, whereas JSON only allows strings as keys in object values. Therefore, CBOR maps with keys other than UTF-8 strings are rejected. + +Tagged items + +Tagged items will throw a parse error by default. They can be ignored by passing `cbor_tag_handler_t::ignore` to function `from_cbor`. They can be stored by passing `cbor_tag_handler_t::store` to function `from_cbor`. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0xa2, 0x67, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, + 0x74, 0xf5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x00 + }; + + // deserialize it with CBOR + json j = json::from_cbor(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` diff --git a/features/binary_formats/index.html b/features/binary_formats/index.html index 4b1dda714..907033843 100644 --- a/features/binary_formats/index.html +++ b/features/binary_formats/index.html @@ -1 +1 @@ - Binary Formats - JSON for Modern C++

    Binary Formats

    Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance, over a network. Hence, the library supports

    to efficiently encode JSON values to byte vectors and to decode such vectors.

    Comparison

    Completeness

    Format Serialization Deserialization
    BJData complete complete
    BSON incomplete: top-level value must be an object incomplete, but all JSON types are supported
    CBOR complete incomplete, but all JSON types are supported
    MessagePack complete complete
    UBJSON complete complete

    Binary values

    Format Binary values Binary subtypes
    BJData not supported not supported
    BSON supported supported
    CBOR supported supported
    MessagePack supported supported
    UBJSON not supported not supported

    See binary values for more information.

    Sizes

    Format canada.json twitter.json citm_catalog.json jeopardy.json
    BJData 53.2 % 91.1 % 78.1 % 96.6 %
    BJData (size) 58.6 % 92.1 % 86.7 % 97.4 %
    BJData (size+type) 58.6 % 92.1 % 86.5 % 97.4 %
    BSON 85.8 % 95.2 % 95.8 % 106.7 %
    CBOR 50.5 % 86.3 % 68.4 % 88.0 %
    MessagePack 50.5 % 86.0 % 68.5 % 87.9 %
    UBJSON 53.2 % 91.3 % 78.2 % 96.6 %
    UBJSON (size) 58.6 % 92.3 % 86.8 % 97.4 %
    UBJSON (size+type) 55.9 % 92.3 % 85.0 % 95.0 %

    Sizes compared to minified JSON value.

    \ No newline at end of file + Binary Formats - JSON for Modern C++

    Binary Formats

    Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance, over a network. Hence, the library supports

    to efficiently encode JSON values to byte vectors and to decode such vectors.

    Comparison

    Completeness

    Format Serialization Deserialization
    BJData complete complete
    BSON incomplete: top-level value must be an object incomplete, but all JSON types are supported
    CBOR complete incomplete, but all JSON types are supported
    MessagePack complete complete
    UBJSON complete complete

    Binary values

    Format Binary values Binary subtypes
    BJData not supported not supported
    BSON supported supported
    CBOR supported supported
    MessagePack supported supported
    UBJSON not supported not supported

    See binary values for more information.

    Sizes

    Format canada.json twitter.json citm_catalog.json jeopardy.json
    BJData 53.2 % 91.1 % 78.1 % 96.6 %
    BJData (size) 58.6 % 92.1 % 86.7 % 97.4 %
    BJData (size+type) 58.6 % 92.1 % 86.5 % 97.4 %
    BSON 85.8 % 95.2 % 95.8 % 106.7 %
    CBOR 50.5 % 86.3 % 68.4 % 88.0 %
    MessagePack 50.5 % 86.0 % 68.5 % 87.9 %
    UBJSON 53.2 % 91.3 % 78.2 % 96.6 %
    UBJSON (size) 58.6 % 92.3 % 86.8 % 97.4 %
    UBJSON (size+type) 55.9 % 92.3 % 85.0 % 95.0 %

    Sizes compared to minified JSON value.

    \ No newline at end of file diff --git a/features/binary_formats/index.md b/features/binary_formats/index.md new file mode 100644 index 000000000..20bd14438 --- /dev/null +++ b/features/binary_formats/index.md @@ -0,0 +1,51 @@ +# Binary Formats + +Though JSON is a ubiquitous data format, it is not a very compact format suitable for data exchange, for instance, over a network. Hence, the library supports + +- [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md) (Binary JData), +- [BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md) (Binary JSON), +- [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md) (Concise Binary Object Representation), +- [MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md), and +- [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) (Universal Binary JSON) + +to efficiently encode JSON values to byte vectors and to decode such vectors. + +## Comparison + +### Completeness + +| Format | Serialization | Deserialization | +| ----------- | --------------------------------------------- | -------------------------------------------- | +| BJData | complete | complete | +| BSON | incomplete: top-level value must be an object | incomplete, but all JSON types are supported | +| CBOR | complete | incomplete, but all JSON types are supported | +| MessagePack | complete | complete | +| UBJSON | complete | complete | + +### Binary values + +| Format | Binary values | Binary subtypes | +| ----------- | ------------- | --------------- | +| BJData | not supported | not supported | +| BSON | supported | supported | +| CBOR | supported | supported | +| MessagePack | supported | supported | +| UBJSON | not supported | not supported | + +See [binary values](https://json.nlohmann.me/features/binary_values/index.md) for more information. + +### Sizes + +| Format | canada.json | twitter.json | citm_catalog.json | jeopardy.json | +| ------------------ | ----------- | ------------ | ----------------- | ------------- | +| BJData | 53.2 % | 91.1 % | 78.1 % | 96.6 % | +| BJData (size) | 58.6 % | 92.1 % | 86.7 % | 97.4 % | +| BJData (size+type) | 58.6 % | 92.1 % | 86.5 % | 97.4 % | +| BSON | 85.8 % | 95.2 % | 95.8 % | 106.7 % | +| CBOR | 50.5 % | 86.3 % | 68.4 % | 88.0 % | +| MessagePack | 50.5 % | 86.0 % | 68.5 % | 87.9 % | +| UBJSON | 53.2 % | 91.3 % | 78.2 % | 96.6 % | +| UBJSON (size) | 58.6 % | 92.3 % | 86.8 % | 97.4 % | +| UBJSON (size+type) | 55.9 % | 92.3 % | 85.0 % | 95.0 % | + +Sizes compared to minified JSON value. diff --git a/features/binary_formats/messagepack.md b/features/binary_formats/messagepack.md new file mode 100644 index 000000000..b2f69f174 --- /dev/null +++ b/features/binary_formats/messagepack.md @@ -0,0 +1,143 @@ +# MessagePack + +MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. +But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one +extra byte in addition to the strings themselves. + +!!! abstract "References" + + - [MessagePack website](https://msgpack.org) + - [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md) + +## Serialization + +The library uses the following mapping from JSON values types to MessagePack types according to the MessagePack +specification: + +| JSON value type | value/range | MessagePack type | first byte | +|-----------------|------------------------------------------|------------------|------------| +| null | `null` | nil | 0xC0 | +| boolean | `true` | true | 0xC3 | +| boolean | `false` | false | 0xC2 | +| number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 | +| number_integer | -2147483648..-32769 | int32 | 0xD2 | +| number_integer | -32768..-129 | int16 | 0xD1 | +| number_integer | -128..-33 | int8 | 0xD0 | +| number_integer | -32..-1 | negative fixint | 0xE0..0xFF | +| number_integer | 0..127 | positive fixint | 0x00..0x7F | +| number_integer | 128..255 | uint 8 | 0xCC | +| number_integer | 256..65535 | uint 16 | 0xCD | +| number_integer | 65536..4294967295 | uint 32 | 0xCE | +| number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF | +| number_unsigned | 0..127 | positive fixint | 0x00..0x7F | +| number_unsigned | 128..255 | uint 8 | 0xCC | +| number_unsigned | 256..65535 | uint 16 | 0xCD | +| number_unsigned | 65536..4294967295 | uint 32 | 0xCE | +| number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF | +| number_float | *any value representable by a float* | float 32 | 0xCA | +| number_float | *any value NOT representable by a float* | float 64 | 0xCB | +| string | *length*: 0..31 | fixstr | 0xA0..0xBF | +| string | *length*: 32..255 | str 8 | 0xD9 | +| string | *length*: 256..65535 | str 16 | 0xDA | +| string | *length*: 65536..4294967295 | str 32 | 0xDB | +| array | *size*: 0..15 | fixarray | 0x90..0x9F | +| array | *size*: 16..65535 | array 16 | 0xDC | +| array | *size*: 65536..4294967295 | array 32 | 0xDD | +| object | *size*: 0..15 | fix map | 0x80..0x8F | +| object | *size*: 16..65535 | map 16 | 0xDE | +| object | *size*: 65536..4294967295 | map 32 | 0xDF | +| binary | *size*: 0..255 | bin 8 | 0xC4 | +| binary | *size*: 256..65535 | bin 16 | 0xC5 | +| binary | *size*: 65536..4294967295 | bin 32 | 0xC6 | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a MessagePack value. + + Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. + +!!! warning "Size constraints" + + The following values can **not** be converted to a MessagePack value: + + - strings with more than 4294967295 bytes + - byte strings with more than 4294967295 bytes + - arrays with more than 4294967295 elements + - objects with more than 4294967295 elements + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly in contrast to the + [dump](../../api/basic_json/dump.md) function which serializes NaN or Infinity to `null`. + +??? example + + ```cpp + --8<-- "examples/to_msgpack.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_msgpack.output" + ``` + +## Deserialization + +The library maps MessagePack types to JSON value types as follows: + +| MessagePack type | JSON value type | first byte | +|------------------|-----------------|------------| +| positive fixint | number_unsigned | 0x00..0x7F | +| fixmap | object | 0x80..0x8F | +| fixarray | array | 0x90..0x9F | +| fixstr | string | 0xA0..0xBF | +| nil | `null` | 0xC0 | +| false | `false` | 0xC2 | +| true | `true` | 0xC3 | +| float 32 | number_float | 0xCA | +| float 64 | number_float | 0xCB | +| uint 8 | number_unsigned | 0xCC | +| uint 16 | number_unsigned | 0xCD | +| uint 32 | number_unsigned | 0xCE | +| uint 64 | number_unsigned | 0xCF | +| int 8 | number_integer | 0xD0 | +| int 16 | number_integer | 0xD1 | +| int 32 | number_integer | 0xD2 | +| int 64 | number_integer | 0xD3 | +| str 8 | string | 0xD9 | +| str 16 | string | 0xDA | +| str 32 | string | 0xDB | +| array 16 | array | 0xDC | +| array 32 | array | 0xDD | +| map 16 | object | 0xDE | +| map 32 | object | 0xDF | +| bin 8 | binary | 0xC4 | +| bin 16 | binary | 0xC5 | +| bin 32 | binary | 0xC6 | +| ext 8 | binary | 0xC7 | +| ext 16 | binary | 0xC8 | +| ext 32 | binary | 0xC9 | +| fixext 1 | binary | 0xD4 | +| fixext 2 | binary | 0xD5 | +| fixext 4 | binary | 0xD6 | +| fixext 8 | binary | 0xD7 | +| fixext 16 | binary | 0xD8 | +| negative fixint | number_integer | 0xE0-0xFF | + +!!! info + + Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. + + +??? example + + ```cpp + --8<-- "examples/from_msgpack.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_msgpack.output" + ``` diff --git a/features/binary_formats/messagepack/index.html b/features/binary_formats/messagepack/index.html index 2a15bb15d..b26d75a39 100644 --- a/features/binary_formats/messagepack/index.html +++ b/features/binary_formats/messagepack/index.html @@ -45,4 +45,4 @@ "compact": true, "schema": 0 } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/binary_formats/messagepack/index.md b/features/binary_formats/messagepack/index.md new file mode 100644 index 000000000..3cd51ba21 --- /dev/null +++ b/features/binary_formats/messagepack/index.md @@ -0,0 +1,181 @@ +# MessagePack + +MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves. + +References + +- [MessagePack website](https://msgpack.org) +- [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md) + +## Serialization + +The library uses the following mapping from JSON values types to MessagePack types according to the MessagePack specification: + +| JSON value type | value/range | MessagePack type | first byte | +| --------------- | ---------------------------------------- | ---------------- | ---------- | +| null | `null` | nil | 0xC0 | +| boolean | `true` | true | 0xC3 | +| boolean | `false` | false | 0xC2 | +| number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3 | +| number_integer | -2147483648..-32769 | int32 | 0xD2 | +| number_integer | -32768..-129 | int16 | 0xD1 | +| number_integer | -128..-33 | int8 | 0xD0 | +| number_integer | -32..-1 | negative fixint | 0xE0..0xFF | +| number_integer | 0..127 | positive fixint | 0x00..0x7F | +| number_integer | 128..255 | uint 8 | 0xCC | +| number_integer | 256..65535 | uint 16 | 0xCD | +| number_integer | 65536..4294967295 | uint 32 | 0xCE | +| number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF | +| number_unsigned | 0..127 | positive fixint | 0x00..0x7F | +| number_unsigned | 128..255 | uint 8 | 0xCC | +| number_unsigned | 256..65535 | uint 16 | 0xCD | +| number_unsigned | 65536..4294967295 | uint 32 | 0xCE | +| number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF | +| number_float | *any value representable by a float* | float 32 | 0xCA | +| number_float | *any value NOT representable by a float* | float 64 | 0xCB | +| string | *length*: 0..31 | fixstr | 0xA0..0xBF | +| string | *length*: 32..255 | str 8 | 0xD9 | +| string | *length*: 256..65535 | str 16 | 0xDA | +| string | *length*: 65536..4294967295 | str 32 | 0xDB | +| array | *size*: 0..15 | fixarray | 0x90..0x9F | +| array | *size*: 16..65535 | array 16 | 0xDC | +| array | *size*: 65536..4294967295 | array 32 | 0xDD | +| object | *size*: 0..15 | fix map | 0x80..0x8F | +| object | *size*: 16..65535 | map 16 | 0xDE | +| object | *size*: 65536..4294967295 | map 32 | 0xDF | +| binary | *size*: 0..255 | bin 8 | 0xC4 | +| binary | *size*: 256..65535 | bin 16 | 0xC5 | +| binary | *size*: 65536..4294967295 | bin 32 | 0xC6 | + +Complete mapping + +The mapping is **complete** in the sense that any JSON value type can be converted to a MessagePack value. + +Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. + +Size constraints + +The following values can **not** be converted to a MessagePack value: + +- strings with more than 4294967295 bytes +- byte strings with more than 4294967295 bytes +- arrays with more than 4294967295 elements +- objects with more than 4294967295 elements + +NaN/infinity handling + +If NaN or Infinity are stored inside a JSON number, they are serialized properly in contrast to the [dump](https://json.nlohmann.me/api/basic_json/dump/index.md) function which serializes NaN or Infinity to `null`. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": 0})"_json; + + // serialize it to MessagePack + std::vector v = json::to_msgpack(j); + + // print the vector content + for (auto& byte : v) + { + std::cout << "0x" << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " "; + } + std::cout << std::endl; +} +``` + +Output: + +``` +0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 +``` + +## Deserialization + +The library maps MessagePack types to JSON value types as follows: + +| MessagePack type | JSON value type | first byte | +| ---------------- | --------------- | ---------- | +| positive fixint | number_unsigned | 0x00..0x7F | +| fixmap | object | 0x80..0x8F | +| fixarray | array | 0x90..0x9F | +| fixstr | string | 0xA0..0xBF | +| nil | `null` | 0xC0 | +| false | `false` | 0xC2 | +| true | `true` | 0xC3 | +| float 32 | number_float | 0xCA | +| float 64 | number_float | 0xCB | +| uint 8 | number_unsigned | 0xCC | +| uint 16 | number_unsigned | 0xCD | +| uint 32 | number_unsigned | 0xCE | +| uint 64 | number_unsigned | 0xCF | +| int 8 | number_integer | 0xD0 | +| int 16 | number_integer | 0xD1 | +| int 32 | number_integer | 0xD2 | +| int 64 | number_integer | 0xD3 | +| str 8 | string | 0xD9 | +| str 16 | string | 0xDA | +| str 32 | string | 0xDB | +| array 16 | array | 0xDC | +| array 32 | array | 0xDD | +| map 16 | object | 0xDE | +| map 32 | object | 0xDF | +| bin 8 | binary | 0xC4 | +| bin 16 | binary | 0xC5 | +| bin 32 | binary | 0xC6 | +| ext 8 | binary | 0xC7 | +| ext 16 | binary | 0xC8 | +| ext 32 | binary | 0xC9 | +| fixext 1 | binary | 0xD4 | +| fixext 2 | binary | 0xD5 | +| fixext 4 | binary | 0xD6 | +| fixext 8 | binary | 0xD7 | +| fixext 16 | binary | 0xD8 | +| negative fixint | number_integer | 0xE0-0xFF | + +Info + +Any MessagePack output created by `to_msgpack` can be successfully parsed by `from_msgpack`. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, + 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x00 + }; + + // deserialize it with MessagePack + json j = json::from_msgpack(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` diff --git a/features/binary_formats/ubjson.md b/features/binary_formats/ubjson.md new file mode 100644 index 000000000..76956d60a --- /dev/null +++ b/features/binary_formats/ubjson.md @@ -0,0 +1,126 @@ +# UBJSON + +Universal Binary JSON (UBJSON) is a binary form directly imitating JSON, but requiring fewer bytes of data. It aims to +achieve the generality of JSON, combined with being much easier to process than JSON. + +!!! abstract "References" + + - [UBJSON Website](http://ubjson.org) + +## Serialization + +The library uses the following mapping from JSON values types to UBJSON types according to the UBJSON specification: + +| JSON value type | value/range | UBJSON type | marker | +|-----------------|-----------------------------------|----------------|--------| +| null | `null` | null | `Z` | +| boolean | `true` | true | `T` | +| boolean | `false` | false | `F` | +| number_integer | -9223372036854775808..-2147483649 | int64 | `L` | +| number_integer | -2147483648..-32769 | int32 | `l` | +| number_integer | -32768..-129 | int16 | `I` | +| number_integer | -128..127 | int8 | `i` | +| number_integer | 128..255 | uint8 | `U` | +| number_integer | 256..32767 | int16 | `I` | +| number_integer | 32768..2147483647 | int32 | `l` | +| number_integer | 2147483648..9223372036854775807 | int64 | `L` | +| number_unsigned | 0..127 | int8 | `i` | +| number_unsigned | 128..255 | uint8 | `U` | +| number_unsigned | 256..32767 | int16 | `I` | +| number_unsigned | 32768..2147483647 | int32 | `l` | +| number_unsigned | 2147483648..9223372036854775807 | int64 | `L` | +| number_unsigned | 2147483649..18446744073709551615 | high-precision | `H` | +| number_float | *any value* | float64 | `D` | +| string | *with shortest length indicator* | string | `S` | +| array | *see notes on optimized format* | array | `[` | +| object | *see notes on optimized format* | map | `{` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any JSON value type can be converted to a UBJSON value. + + Any UBJSON output created by `to_ubjson` can be successfully parsed by `from_ubjson`. + +!!! warning "Size constraints" + + The following values can **not** be converted to a UBJSON value: + + - strings with more than 9223372036854775807 bytes (theoretical) + +!!! info "Unused UBJSON markers" + + The following markers are not used in the conversion: + + - `Z`: no-op values are not created. + - `C`: single-byte strings are serialized with `S` markers. + +!!! info "NaN/infinity handling" + + If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the + `dump()` function which serializes NaN or Infinity to `null`. + +!!! info "Optimized formats" + + The optimized formats for containers are supported: Parameter `use_size` adds size information to the beginning of a + container and removes the closing marker. Parameter `use_type` further checks whether all elements of a container + have the same type and adds the type marker to the beginning of the container. The `use_type` parameter must only be + used together with `use_size = true`. + + Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the + receiving side is immediately informed on the number of elements of the container. + +!!! info "Binary values" + + If the JSON data contains the binary type, the value stored is a list of integers, as suggested by the UBJSON + documentation. In particular, this means that serialization and the deserialization of a JSON containing binary + values into UBJSON and back will result in a different JSON object. + +??? example + + ```cpp + --8<-- "examples/to_ubjson.cpp" + ``` + + Output: + + ```c + --8<-- "examples/to_ubjson.output" + ``` + +## Deserialization + +The library maps UBJSON types to JSON value types as follows: + +| UBJSON type | JSON value type | marker | +|-------------|-----------------------------------------|--------| +| no-op | *no value, next value is read* | `N` | +| null | `null` | `Z` | +| false | `false` | `F` | +| true | `true` | `T` | +| float32 | number_float | `d` | +| float64 | number_float | `D` | +| uint8 | number_unsigned | `U` | +| int8 | number_integer | `i` | +| int16 | number_integer | `I` | +| int32 | number_integer | `l` | +| int64 | number_integer | `L` | +| string | string | `S` | +| char | string | `C` | +| array | array (optimized values are supported) | `[` | +| object | object (optimized values are supported) | `{` | + +!!! success "Complete mapping" + + The mapping is **complete** in the sense that any UBJSON value can be converted to a JSON value. + +??? example + + ```cpp + --8<-- "examples/from_ubjson.cpp" + ``` + + Output: + + ```json + --8<-- "examples/from_ubjson.output" + ``` diff --git a/features/binary_formats/ubjson/index.html b/features/binary_formats/ubjson/index.html index 1c2f6cd24..98bdf3a8e 100644 --- a/features/binary_formats/ubjson/index.html +++ b/features/binary_formats/ubjson/index.html @@ -90,4 +90,4 @@ "compact": true, "schema": 0 } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/binary_formats/ubjson/index.md b/features/binary_formats/ubjson/index.md new file mode 100644 index 000000000..ae01272b8 --- /dev/null +++ b/features/binary_formats/ubjson/index.md @@ -0,0 +1,206 @@ +# UBJSON + +Universal Binary JSON (UBJSON) is a binary form directly imitating JSON, but requiring fewer bytes of data. It aims to achieve the generality of JSON, combined with being much easier to process than JSON. + +References + +- [UBJSON Website](http://ubjson.org) + +## Serialization + +The library uses the following mapping from JSON values types to UBJSON types according to the UBJSON specification: + +| JSON value type | value/range | UBJSON type | marker | +| --------------- | --------------------------------- | -------------- | ------ | +| null | `null` | null | `Z` | +| boolean | `true` | true | `T` | +| boolean | `false` | false | `F` | +| number_integer | -9223372036854775808..-2147483649 | int64 | `L` | +| number_integer | -2147483648..-32769 | int32 | `l` | +| number_integer | -32768..-129 | int16 | `I` | +| number_integer | -128..127 | int8 | `i` | +| number_integer | 128..255 | uint8 | `U` | +| number_integer | 256..32767 | int16 | `I` | +| number_integer | 32768..2147483647 | int32 | `l` | +| number_integer | 2147483648..9223372036854775807 | int64 | `L` | +| number_unsigned | 0..127 | int8 | `i` | +| number_unsigned | 128..255 | uint8 | `U` | +| number_unsigned | 256..32767 | int16 | `I` | +| number_unsigned | 32768..2147483647 | int32 | `l` | +| number_unsigned | 2147483648..9223372036854775807 | int64 | `L` | +| number_unsigned | 2147483649..18446744073709551615 | high-precision | `H` | +| number_float | *any value* | float64 | `D` | +| string | *with shortest length indicator* | string | `S` | +| array | *see notes on optimized format* | array | `[` | +| object | *see notes on optimized format* | map | `{` | + +Complete mapping + +The mapping is **complete** in the sense that any JSON value type can be converted to a UBJSON value. + +Any UBJSON output created by `to_ubjson` can be successfully parsed by `from_ubjson`. + +Size constraints + +The following values can **not** be converted to a UBJSON value: + +- strings with more than 9223372036854775807 bytes (theoretical) + +Unused UBJSON markers + +The following markers are not used in the conversion: + +- `Z`: no-op values are not created. +- `C`: single-byte strings are serialized with `S` markers. + +NaN/infinity handling + +If NaN or Infinity are stored inside a JSON number, they are serialized properly. This behavior differs from the `dump()` function which serializes NaN or Infinity to `null`. + +Optimized formats + +The optimized formats for containers are supported: Parameter `use_size` adds size information to the beginning of a container and removes the closing marker. Parameter `use_type` further checks whether all elements of a container have the same type and adds the type marker to the beginning of the container. The `use_type` parameter must only be used together with `use_size = true`. + +Note that `use_size = true` alone may result in larger representations - the benefit of this parameter is that the receiving side is immediately informed on the number of elements of the container. + +Binary values + +If the JSON data contains the binary type, the value stored is a list of integers, as suggested by the UBJSON documentation. In particular, this means that serialization and the deserialization of a JSON containing binary values into UBJSON and back will result in a different JSON object. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +// function to print UBJSON's diagnostic format +void print_byte(uint8_t byte) +{ + if (32 < byte and byte < 128) + { + std::cout << (char)byte; + } + else + { + std::cout << (int)byte; + } +} + +int main() +{ + // create a JSON value + json j = R"({"compact": true, "schema": false})"_json; + + // serialize it to UBJSON + std::vector v = json::to_ubjson(j); + + // print the vector content + for (auto& byte : v) + { + print_byte(byte); + } + std::cout << std::endl; + + // create an array of numbers + json array = {1, 2, 3, 4, 5, 6, 7, 8}; + + // serialize it to UBJSON using default representation + std::vector v_array = json::to_ubjson(array); + // serialize it to UBJSON using size optimization + std::vector v_array_size = json::to_ubjson(array, true); + // serialize it to UBJSON using type optimization + std::vector v_array_size_and_type = json::to_ubjson(array, true, true); + + // print the vector contents + for (auto& byte : v_array) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size) + { + print_byte(byte); + } + std::cout << std::endl; + + for (auto& byte : v_array_size_and_type) + { + print_byte(byte); + } + std::cout << std::endl; +} +``` + +Output: + +``` +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 +``` + +## Deserialization + +The library maps UBJSON types to JSON value types as follows: + +| UBJSON type | JSON value type | marker | +| ----------- | --------------------------------------- | ------ | +| no-op | *no value, next value is read* | `N` | +| null | `null` | `Z` | +| false | `false` | `F` | +| true | `true` | `T` | +| float32 | number_float | `d` | +| float64 | number_float | `D` | +| uint8 | number_unsigned | `U` | +| int8 | number_integer | `i` | +| int16 | number_integer | `I` | +| int32 | number_integer | `l` | +| int64 | number_integer | `L` | +| string | string | `S` | +| char | string | `C` | +| array | array (optimized values are supported) | `[` | +| object | object (optimized values are supported) | `{` | + +Complete mapping + +The mapping is **complete** in the sense that any UBJSON value can be converted to a JSON value. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create byte vector + std::vector v = {0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, + 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D + }; + + // deserialize it with UBJSON + json j = json::from_ubjson(v); + + // print the deserialized JSON value + std::cout << std::setw(2) << j << std::endl; +} +``` + +Output: + +``` +{ + "compact": true, + "schema": 0 +} +``` diff --git a/features/binary_values.md b/features/binary_values.md new file mode 100644 index 000000000..79629383f --- /dev/null +++ b/features/binary_values.md @@ -0,0 +1,374 @@ +# Binary Values + +The library implements several [binary formats](binary_formats/index.md) that encode JSON in an efficient way. Most of +these formats support binary values; that is, values that have semantics defined outside the library and only define a +sequence of bytes to be stored. + +JSON itself does not have a binary value. As such, binary values are an extension that this library implements to store +values received by a binary format. Binary values are never created by the JSON parser and are only part of a +serialized JSON text if they have been created manually or via a binary format. + +## API for binary values + +```mermaid +classDiagram + +class binary_t ["json::binary_t"] { + +void set_subtype(std::uint64_t subtype) + +void clear_subtype() + +std::uint64_t subtype() const + +bool has_subtype() const +} + +class vector ["std::vector"] + +vector <|-- binary_t +``` + +By default, binary values are stored as `std::vector`. This type can be changed by providing a template +parameter to the `basic_json` type. To store binary subtypes, the storage type is extended and exposed as +`json::binary_t`: + +```cpp +auto binary = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}); +auto binary_with_subtype = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}, 42); +``` + +There are several convenience functions to check and set the subtype: + +```cpp +binary.has_subtype(); // returns false +binary_with_subtype.has_subtype(); // returns true + +binary_with_subtype.clear_subtype(); +binary_with_subtype.has_subtype(); // returns false + +binary_with_subtype.set_subtype(42); +binary.set_subtype(23); + +binary.subtype(); // returns 23 +``` + +As `json::binary_t` is subclassing `std::vector`, all member functions are available: + +```cpp +binary.size(); // returns 4 +binary[1]; // returns 0xFE +``` + +JSON values can be constructed from `json::binary_t`: + +```cpp +json j = binary; +``` + +Binary values are primitive values just like numbers or strings: + +```cpp +j.is_binary(); // returns true +j.is_primitive(); // returns true +``` + +Given a binary JSON value, the `binary_t` can be accessed by reference as via `get_binary()`: + +```cpp +j.get_binary().has_subtype(); // returns true +j.get_binary().size(); // returns 4 +``` + +For convenience, binary JSON values can be constructed via `json::binary`: + +```cpp +auto j2 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 23); +auto j3 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}); + +j2 == j; // returns true +j3.get_binary().has_subtype(); // returns false +j3.get_binary().subtype(); // returns std::uint64_t(-1) as j3 has no subtype +``` + + + +## Serialization + +Binary values are serialized differently according to the formats. + +### JSON + +JSON does not have a binary type, and this library does not introduce a new type as this would break conformance. +Instead, binary values are serialized as an object with two keys: `bytes` holds an array of integers, and `subtype` +is an integer or `null`. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // serialize to standard output + std::cout << j.dump(2) << std::endl; + ``` + + Output: + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } + } + ``` + +!!! warning "No roundtrip for binary values" + + The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to + remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes. + +### BJData + +[BJData](binary_formats/bjdata.md) neither supports binary values nor subtypes and proposes to serialize binary values +as an array of uint8 values. The library implements this translation. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 (will be ignored in BJData) + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to BJData + auto v = json::to_bjdata(j); + ``` + + `v` is a `std::vector` with the following 20 elements: + + ```c + 0x7B // '{' + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' + 0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE // content (each byte prefixed with 'U') + 0x5D // ']' + 0x7D // '}' + ``` + + The following code uses the type and size optimization for BJData: + + ```cpp + // convert to BJData using the size and type optimization + auto v = json::to_bjdata(j, true, true); + ``` + + The resulting vector has 22 elements; the optimization is not effective for examples with few values: + + ```c + 0x7B // '{' + 0x23 0x69 0x01 // '#' 'i' type of the array elements: unsigned integers + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' array + 0x24 0x55 // '$' 'U' type of the array elements: unsigned integers + 0x23 0x69 0x04 // '#' i 4 number of array elements + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that subtype (42) is **not** serialized and that BJData has **no binary type**, and deserializing `v` would + yield the following value: + + ```json + { + "binary": [202, 254, 186, 190] + } + ``` + +### BSON + +[BSON](binary_formats/bson.md) supports binary values and subtypes. If a subtype is given, it is used and added as an +unsigned 8-bit integer. If no subtype is given, the generic binary subtype 0x00 is used. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to BSON + auto v = json::to_bson(j); + ``` + + `v` is a `std::vector` with the following 22 elements: + + ```c + 0x16 0x00 0x00 0x00 // number of bytes in the document + 0x05 // binary value + 0x62 0x69 0x6E 0x61 0x72 0x79 0x00 // key "binary" + null byte + 0x04 0x00 0x00 0x00 // number of bytes + 0x2a // subtype + 0xCA 0xFE 0xBA 0xBE // content + 0x00 // end of the document + ``` + + Note that the serialization preserves the subtype, and deserializing `v` would yield the following value: + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } + } + ``` + +### CBOR + +[CBOR](binary_formats/cbor.md) supports binary values, but no subtypes. Subtypes will be serialized as tags. Any binary +value will be serialized as byte strings. The library will choose the smallest representation using the length of the +byte array. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to CBOR + auto v = json::to_cbor(j); + ``` + + `v` is a `std::vector` with the following 15 elements: + + ```c + 0xA1 // map(1) + 0x66 // text(6) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0xD8 0x2A // tag(42) + 0x44 // bytes(4) + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that the subtype is serialized as tag. However, parsing tagged values yield a parse error unless + `json::cbor_tag_handler_t::ignore` or `json::cbor_tag_handler_t::store` is passed to `json::from_cbor`. + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": null + } + } + ``` + +### MessagePack + +[MessagePack](binary_formats/messagepack.md) supports binary values and subtypes. If a subtype is given, the ext family +is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, ext8, ext16, and +ext32. The subtype is then added as a signed 8-bit integer. + +If no subtype is given, the bin family (bin8, bin16, bin32) is used. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to MessagePack + auto v = json::to_msgpack(j); + ``` + + `v` is a `std::vector` with the following 14 elements: + + ```c + 0x81 // fixmap1 + 0xA6 // fixstr6 + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0xD6 // fixext4 + 0x2A // subtype + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that the serialization preserves the subtype, and deserializing `v` would yield the following value: + + ```json + { + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } + } + ``` + +### UBJSON + +[UBJSON](binary_formats/ubjson.md) neither supports binary values nor subtypes and proposes to serialize binary values +as an array of uint8 values. The library implements this translation. + +??? example + + Code: + + ```cpp + // create a binary value of subtype 42 (will be ignored in UBJSON) + json j; + j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + + // convert to UBJSON + auto v = json::to_ubjson(j); + ``` + + `v` is a `std::vector` with the following 20 elements: + + ```c + 0x7B // '{' + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' + 0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE // content (each byte prefixed with 'U') + 0x5D // ']' + 0x7D // '}' + ``` + + The following code uses the type and size optimization for UBJSON: + + ```cpp + // convert to UBJSON using the size and type optimization + auto v = json::to_ubjson(j, true, true); + ``` + + The resulting vector has 23 elements; the optimization is not effective for examples with few values: + + ```c + 0x7B // '{' + 0x24 // '$' type of the object elements + 0x5B // '[' array + 0x23 0x69 0x01 // '#' i 1 number of object elements + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x24 0x55 // '$' 'U' type of the array elements: unsigned integers + 0x23 0x69 0x04 // '#' i 4 number of array elements + 0xCA 0xFE 0xBA 0xBE // content + ``` + + Note that subtype (42) is **not** serialized and that UBJSON has **no binary type**, and deserializing `v` would + yield the following value: + + ```json + { + "binary": [202, 254, 186, 190] + } + ``` diff --git a/features/binary_values/index.html b/features/binary_values/index.html index 62aeb44bc..7b8539d73 100644 --- a/features/binary_values/index.html +++ b/features/binary_values/index.html @@ -154,4 +154,4 @@ vector <|-- binary_t

    By default, binary values are stored as

    Note that subtype (42) is not serialized and that UBJSON has no binary type, and deserializing v would yield the following value:

    {
       "binary": [202, 254, 186, 190]
     }
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/binary_values/index.md b/features/binary_values/index.md new file mode 100644 index 000000000..c23265653 --- /dev/null +++ b/features/binary_values/index.md @@ -0,0 +1,353 @@ +# Binary Values + +The library implements several [binary formats](https://json.nlohmann.me/features/binary_formats/index.md) that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics defined outside the library and only define a sequence of bytes to be stored. + +JSON itself does not have a binary value. As such, binary values are an extension that this library implements to store values received by a binary format. Binary values are never created by the JSON parser and are only part of a serialized JSON text if they have been created manually or via a binary format. + +## API for binary values + +``` +classDiagram + +class binary_t ["json::binary_t"] { + +void set_subtype(std::uint64_t subtype) + +void clear_subtype() + +std::uint64_t subtype() const + +bool has_subtype() const +} + +class vector ["std::vector"] + +vector <|-- binary_t +``` + +By default, binary values are stored as `std::vector`. This type can be changed by providing a template parameter to the `basic_json` type. To store binary subtypes, the storage type is extended and exposed as `json::binary_t`: + +``` +auto binary = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}); +auto binary_with_subtype = json::binary_t({0xCA, 0xFE, 0xBA, 0xBE}, 42); +``` + +There are several convenience functions to check and set the subtype: + +``` +binary.has_subtype(); // returns false +binary_with_subtype.has_subtype(); // returns true + +binary_with_subtype.clear_subtype(); +binary_with_subtype.has_subtype(); // returns false + +binary_with_subtype.set_subtype(42); +binary.set_subtype(23); + +binary.subtype(); // returns 23 +``` + +As `json::binary_t` is subclassing `std::vector`, all member functions are available: + +``` +binary.size(); // returns 4 +binary[1]; // returns 0xFE +``` + +JSON values can be constructed from `json::binary_t`: + +``` +json j = binary; +``` + +Binary values are primitive values just like numbers or strings: + +``` +j.is_binary(); // returns true +j.is_primitive(); // returns true +``` + +Given a binary JSON value, the `binary_t` can be accessed by reference as via `get_binary()`: + +``` +j.get_binary().has_subtype(); // returns true +j.get_binary().size(); // returns 4 +``` + +For convenience, binary JSON values can be constructed via `json::binary`: + +``` +auto j2 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 23); +auto j3 = json::binary({0xCA, 0xFE, 0xBA, 0xBE}); + +j2 == j; // returns true +j3.get_binary().has_subtype(); // returns false +j3.get_binary().subtype(); // returns std::uint64_t(-1) as j3 has no subtype +``` + +## Serialization + +Binary values are serialized differently according to the formats. + +### JSON + +JSON does not have a binary type, and this library does not introduce a new type as this would break conformance. Instead, binary values are serialized as an object with two keys: `bytes` holds an array of integers, and `subtype` is an integer or `null`. + +Example + +Code: + +``` +// create a binary value of subtype 42 +json j; +j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + +// serialize to standard output +std::cout << j.dump(2) << std::endl; +``` + +Output: + +``` +{ + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } +} +``` + +No roundtrip for binary values + +The JSON parser will not parse the objects generated by binary values back to binary values. This is by design to remain standards compliant. Serializing binary values to JSON is only implemented for debugging purposes. + +### BJData + +[BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md) neither supports binary values nor subtypes and proposes to serialize binary values as an array of uint8 values. The library implements this translation. + +Example + +Code: + +``` +// create a binary value of subtype 42 (will be ignored in BJData) +json j; +j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + +// convert to BJData +auto v = json::to_bjdata(j); +``` + +`v` is a `std::vector` with the following 20 elements: + +``` +0x7B // '{' + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' + 0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE // content (each byte prefixed with 'U') + 0x5D // ']' +0x7D // '}' +``` + +The following code uses the type and size optimization for BJData: + +``` +// convert to BJData using the size and type optimization +auto v = json::to_bjdata(j, true, true); +``` + +The resulting vector has 22 elements; the optimization is not effective for examples with few values: + +``` +0x7B // '{' + 0x23 0x69 0x01 // '#' 'i' type of the array elements: unsigned integers + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' array + 0x24 0x55 // '$' 'U' type of the array elements: unsigned integers + 0x23 0x69 0x04 // '#' i 4 number of array elements + 0xCA 0xFE 0xBA 0xBE // content +``` + +Note that subtype (42) is **not** serialized and that BJData has **no binary type**, and deserializing `v` would yield the following value: + +``` +{ + "binary": [202, 254, 186, 190] +} +``` + +### BSON + +[BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md) supports binary values and subtypes. If a subtype is given, it is used and added as an unsigned 8-bit integer. If no subtype is given, the generic binary subtype 0x00 is used. + +Example + +Code: + +``` +// create a binary value of subtype 42 +json j; +j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + +// convert to BSON +auto v = json::to_bson(j); +``` + +`v` is a `std::vector` with the following 22 elements: + +``` +0x16 0x00 0x00 0x00 // number of bytes in the document + 0x05 // binary value + 0x62 0x69 0x6E 0x61 0x72 0x79 0x00 // key "binary" + null byte + 0x04 0x00 0x00 0x00 // number of bytes + 0x2a // subtype + 0xCA 0xFE 0xBA 0xBE // content +0x00 // end of the document +``` + +Note that the serialization preserves the subtype, and deserializing `v` would yield the following value: + +``` +{ + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } +} +``` + +### CBOR + +[CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md) supports binary values, but no subtypes. Subtypes will be serialized as tags. Any binary value will be serialized as byte strings. The library will choose the smallest representation using the length of the byte array. + +Example + +Code: + +``` +// create a binary value of subtype 42 +json j; +j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + +// convert to CBOR +auto v = json::to_cbor(j); +``` + +`v` is a `std::vector` with the following 15 elements: + +``` +0xA1 // map(1) + 0x66 // text(6) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0xD8 0x2A // tag(42) + 0x44 // bytes(4) + 0xCA 0xFE 0xBA 0xBE // content +``` + +Note that the subtype is serialized as tag. However, parsing tagged values yield a parse error unless `json::cbor_tag_handler_t::ignore` or `json::cbor_tag_handler_t::store` is passed to `json::from_cbor`. + +``` +{ + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": null + } +} +``` + +### MessagePack + +[MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md) supports binary values and subtypes. If a subtype is given, the ext family is used. The library will choose the smallest representation among fixext1, fixext2, fixext4, fixext8, ext8, ext16, and ext32. The subtype is then added as a signed 8-bit integer. + +If no subtype is given, the bin family (bin8, bin16, bin32) is used. + +Example + +Code: + +``` +// create a binary value of subtype 42 +json j; +j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + +// convert to MessagePack +auto v = json::to_msgpack(j); +``` + +`v` is a `std::vector` with the following 14 elements: + +``` +0x81 // fixmap1 + 0xA6 // fixstr6 + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0xD6 // fixext4 + 0x2A // subtype + 0xCA 0xFE 0xBA 0xBE // content +``` + +Note that the serialization preserves the subtype, and deserializing `v` would yield the following value: + +``` +{ + "binary": { + "bytes": [202, 254, 186, 190], + "subtype": 42 + } +} +``` + +### UBJSON + +[UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) neither supports binary values nor subtypes and proposes to serialize binary values as an array of uint8 values. The library implements this translation. + +Example + +Code: + +``` +// create a binary value of subtype 42 (will be ignored in UBJSON) +json j; +j["binary"] = json::binary({0xCA, 0xFE, 0xBA, 0xBE}, 42); + +// convert to UBJSON +auto v = json::to_ubjson(j); +``` + +`v` is a `std::vector` with the following 20 elements: + +``` +0x7B // '{' + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x5B // '[' + 0x55 0xCA 0x55 0xFE 0x55 0xBA 0x55 0xBE // content (each byte prefixed with 'U') + 0x5D // ']' +0x7D // '}' +``` + +The following code uses the type and size optimization for UBJSON: + +``` +// convert to UBJSON using the size and type optimization +auto v = json::to_ubjson(j, true, true); +``` + +The resulting vector has 23 elements; the optimization is not effective for examples with few values: + +``` +0x7B // '{' + 0x24 // '$' type of the object elements + 0x5B // '[' array + 0x23 0x69 0x01 // '#' i 1 number of object elements + 0x69 0x06 // i 6 (length of the key) + 0x62 0x69 0x6E 0x61 0x72 0x79 // "binary" + 0x24 0x55 // '$' 'U' type of the array elements: unsigned integers + 0x23 0x69 0x04 // '#' i 4 number of array elements + 0xCA 0xFE 0xBA 0xBE // content +``` + +Note that subtype (42) is **not** serialized and that UBJSON has **no binary type**, and deserializing `v` would yield the following value: + +``` +{ + "binary": [202, 254, 186, 190] +} +``` diff --git a/features/comments.md b/features/comments.md new file mode 100644 index 000000000..dec04e38a --- /dev/null +++ b/features/comments.md @@ -0,0 +1,40 @@ +# Comments + +This library does not support comments *by default*. It does so for three reasons: + +1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript. +2. This was not an oversight: Douglas Crockford [wrote on this](https://news.ycombinator.com/item?id=3912149) in May 2012: + + > I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't. + + > Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser. + +3. It is dangerous for interoperability if some libraries add comment support while others do not. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this. + +However, you can set parameter `ignore_comments` to `#!cpp true` in the [`parse`](../api/basic_json/parse.md) function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace. + +For more information, see [JSON With Commas and Comments (JWCC)](https://nigeltao.github.io/blog/2021/json-with-commas-comments.html). + +!!! example + + Consider the following JSON with comments. + + ```json + { + // update in 2006: removed Pluto + "planets": ["Mercury", "Venus", "Earth", "Mars", + "Jupiter", "Uranus", "Neptune" /*, "Pluto" */] + } + ``` + + When calling `parse` without additional argument, a parse error exception is thrown. If `ignore_comments` is set to `#!cpp true`, the comments are ignored during parsing: + + ```cpp + --8<-- "examples/comments.cpp" + ``` + + Output: + + ``` + --8<-- "examples/comments.output" + ``` diff --git a/features/comments/index.html b/features/comments/index.html index 70561911c..c13b07f19 100644 --- a/features/comments/index.html +++ b/features/comments/index.html @@ -45,4 +45,4 @@ "Neptune" ] } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/comments/index.md b/features/comments/index.md new file mode 100644 index 000000000..3ad03231b --- /dev/null +++ b/features/comments/index.md @@ -0,0 +1,81 @@ +# Comments + +This library does not support comments *by default*. It does so for three reasons: + +1. Comments are not part of the [JSON specification](https://tools.ietf.org/html/rfc8259). You may argue that `//` or `/* */` are allowed in JavaScript, but JSON is not JavaScript. + +1. This was not an oversight: Douglas Crockford [wrote on this](https://news.ycombinator.com/item?id=3912149) in May 2012: + + > I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability. I know that the lack of comments makes some people sad, but it shouldn't. + > + > Suppose you are using JSON to keep configuration files, which you would like to annotate. Go ahead and insert all the comments you like. Then pipe it through JSMin before handing it to your JSON parser. + +1. It is dangerous for interoperability if some libraries add comment support while others do not. Please check [The Harmful Consequences of the Robustness Principle](https://tools.ietf.org/html/draft-iab-protocol-maintenance-01) on this. + +However, you can set parameter `ignore_comments` to `true` in the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function to ignore `//` or `/* */` comments. Comments will then be treated as whitespace. + +For more information, see [JSON With Commas and Comments (JWCC)](https://nigeltao.github.io/blog/2021/json-with-commas-comments.html). + +Example + +Consider the following JSON with comments. + +``` +{ + // update in 2006: removed Pluto + "planets": ["Mercury", "Venus", "Earth", "Mars", + "Jupiter", "Uranus", "Neptune" /*, "Pluto" */] +} +``` + +When calling `parse` without additional argument, a parse error exception is thrown. If `ignore_comments` is set to `true`, the comments are ignored during parsing: + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::string s = R"( + { + // update in 2006: removed Pluto + "planets": ["Mercury", "Venus", "Earth", "Mars", + "Jupiter", "Uranus", "Neptune" /*, "Pluto" */] + } + )"; + + try + { + json j = json::parse(s); + } + catch (json::exception& e) + { + std::cout << e.what() << std::endl; + } + + json j = json::parse(s, + /* callback */ nullptr, + /* allow exceptions */ true, + /* ignore_comments */ true); + std::cout << j.dump(2) << '\n'; +} +``` + +Output: + +``` +[json.exception.parse_error.101] parse error at line 3, column 9: syntax error while parsing object key - invalid literal; last read: ' { /'; expected string literal +{ + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune" + ] +} +``` diff --git a/features/conversions.md b/features/conversions.md new file mode 100644 index 000000000..eaa213324 --- /dev/null +++ b/features/conversions.md @@ -0,0 +1,91 @@ +# Converting values + +A `basic_json` value stores JSON data, but most of the time you want to move that data into ordinary C++ types (an +`#!cpp int`, a `#!cpp std::string`, a `#!cpp std::vector`, or one of your own structs) and back. This page describes how +these conversions work. + +## Getting values out + +The [`get`](../api/basic_json/get.md) function template returns a copy of the stored value converted to the requested +type: + +```cpp +json j = R"({"name": "Mary", "age": 42, "hobbies": ["hiking", "reading"]})"_json; + +auto name = j["name"].get(); // "Mary" +auto age = j["age"].get(); // 42 +auto hobbies = j["hobbies"].get>(); // {"hiking", "reading"} +``` + +!!! note "Getting a string without quotes" + + A frequent point of confusion: use [`get`](../api/basic_json/get.md), **not** [`dump`](serialization.md), to read a + string value. `#!cpp j["name"].get()` yields `#!cpp Mary`, whereas `#!cpp j["name"].dump()` yields the + JSON text `#!cpp "Mary"` (**with** quotes), because `dump` always produces a JSON text. + +Alternatively, [`get_to`](../api/basic_json/get_to.md) writes into an existing variable and deduces the target type, +which avoids repeating it: + +??? example + + ```cpp + --8<-- "examples/get_to.cpp" + ``` + + Output: + + ```json + --8<-- "examples/get_to.output" + ``` + +The library already knows how to convert to and from the scalar types and the STL containers (such as +`#!cpp std::vector`, `#!cpp std::map`, `#!cpp std::array`, `#!cpp std::optional`, and many more). Converting a JSON +object back to a `#!cpp std::map` or a JSON array back to a `#!cpp std::vector` therefore works without any extra code: + +```cpp +json j = {{"one", 1}, {"two", 2}}; +auto m = j.get>(); // {{"one", 1}, {"two", 2}} +``` + +## Implicit conversions + +By default, a JSON value implicitly converts to a compatible C++ type, so the explicit `get` call can often be omitted: + +```cpp +json j = "Hello"; +std::string s = j; // implicit conversion, same as j.get() +``` + +Implicit conversions are convenient but can be surprising (for example, in overload resolution or with `auto`). They can +be disabled by defining [`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) to `#!cpp 0`, +which forces the explicit `get` form and can catch unintended conversions at compile time. + +!!! warning "Conversions do not range-check numbers" + + Just like C++ itself, the `get` family performs numeric conversions without range checks — retrieving a + floating-point value as an integer truncates it, and narrowing conversions may overflow. See + [number conversion](types/number_handling.md#number-conversion) for details and how to guard against it. + +## Putting values in + +The reverse direction works the same way: assigning or constructing a `json` from a C++ value converts it to JSON. + +```cpp +std::vector numbers = {1, 2, 3}; +json j = numbers; // [1,2,3] +``` + +## Your own types + +The conversions above are built in for standard types. To make the same syntax work for **your own** types, provide +`to_json`/`from_json` functions (or use one of the convenience macros). This is described in detail on the +[arbitrary types conversions](arbitrary_types.md) page. Enums can be mapped to strings as described in +[specializing enum conversion](enum_conversion.md). + +## See also + +- [`get`](../api/basic_json/get.md) - get a copy converted to a given type +- [`get_to`](../api/basic_json/get_to.md) - convert into an existing variable +- [`get_ref`](../api/basic_json/get_ref.md) / [`get_ptr`](../api/basic_json/get_ptr.md) - access the stored value without copying +- [Arbitrary types conversions](arbitrary_types.md) - support your own types +- [`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) - toggle implicit conversions diff --git a/features/conversions/index.html b/features/conversions/index.html index ce1d2dba6..f2e7cbcb1 100644 --- a/features/conversions/index.html +++ b/features/conversions/index.html @@ -79,4 +79,4 @@ std::string s = j; // implicit conversion, same as j.get<std::string>()

    Implicit conversions are convenient but can be surprising (for example, in overload resolution or with auto). They can be disabled by defining JSON_USE_IMPLICIT_CONVERSIONS to 0, which forces the explicit get form and can catch unintended conversions at compile time.

    Conversions do not range-check numbers

    Just like C++ itself, the get family performs numeric conversions without range checks — retrieving a floating-point value as an integer truncates it, and narrowing conversions may overflow. See number conversion for details and how to guard against it.

    Putting values in

    The reverse direction works the same way: assigning or constructing a json from a C++ value converts it to JSON.

    std::vector<int> numbers = {1, 2, 3};
     json j = numbers;   // [1,2,3]
    -

    Your own types

    The conversions above are built in for standard types. To make the same syntax work for your own types, provide to_json/from_json functions (or use one of the convenience macros). This is described in detail on the arbitrary types conversions page. Enums can be mapped to strings as described in specializing enum conversion.

    See also

    \ No newline at end of file +

    Your own types

    The conversions above are built in for standard types. To make the same syntax work for your own types, provide to_json/from_json functions (or use one of the convenience macros). This is described in detail on the arbitrary types conversions page. Enums can be mapped to strings as described in specializing enum conversion.

    See also

    \ No newline at end of file diff --git a/features/conversions/index.md b/features/conversions/index.md new file mode 100644 index 000000000..d9f07d0c5 --- /dev/null +++ b/features/conversions/index.md @@ -0,0 +1,144 @@ +# Converting values + +A `basic_json` value stores JSON data, but most of the time you want to move that data into ordinary C++ types (an `int`, a `std::string`, a `std::vector`, or one of your own structs) and back. This page describes how these conversions work. + +## Getting values out + +The [`get`](https://json.nlohmann.me/api/basic_json/get/index.md) function template returns a copy of the stored value converted to the requested type: + +``` +json j = R"({"name": "Mary", "age": 42, "hobbies": ["hiking", "reading"]})"_json; + +auto name = j["name"].get(); // "Mary" +auto age = j["age"].get(); // 42 +auto hobbies = j["hobbies"].get>(); // {"hiking", "reading"} +``` + +Getting a string without quotes + +A frequent point of confusion: use [`get`](https://json.nlohmann.me/api/basic_json/get/index.md), **not** [`dump`](https://json.nlohmann.me/features/serialization/index.md), to read a string value. `j["name"].get()` yields `Mary`, whereas `j["name"].dump()` yields the JSON text `"Mary"` (**with** quotes), because `dump` always produces a JSON text. + +Alternatively, [`get_to`](https://json.nlohmann.me/api/basic_json/get_to/index.md) writes into an existing variable and deduces the target type, which avoids repeating it: + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + bool v1; + int v2; + short v3; + float v4; + int v5; + std::string v6; + std::vector v7; + std::unordered_map v8; + + // use explicit conversions + json_types["boolean"].get_to(v1); + json_types["number"]["integer"].get_to(v2); + json_types["number"]["integer"].get_to(v3); + json_types["number"]["floating-point"].get_to(v4); + json_types["number"]["floating-point"].get_to(v5); + json_types["string"].get_to(v6); + json_types["array"].get_to(v7); + json_types.get_to(v8); + + // print the conversion results + std::cout << v1 << '\n'; + std::cout << v2 << ' ' << v3 << '\n'; + std::cout << v4 << ' ' << v5 << '\n'; + std::cout << v6 << '\n'; + + for (auto i : v7) + { + std::cout << i << ' '; + } + std::cout << "\n\n"; + + for (auto i : v8) + { + std::cout << i.first << ": " << i.second << '\n'; + } +} +``` + +Output: + +``` +1 +42 42 +17.23 17 +Hello, world! +1 2 3 4 5 + +string: "Hello, world!" +number: {"floating-point":17.23,"integer":42} +null: null +boolean: true +array: [1,2,3,4,5] +``` + +The library already knows how to convert to and from the scalar types and the STL containers (such as `std::vector`, `std::map`, `std::array`, `std::optional`, and many more). Converting a JSON object back to a `std::map` or a JSON array back to a `std::vector` therefore works without any extra code: + +``` +json j = {{"one", 1}, {"two", 2}}; +auto m = j.get>(); // {{"one", 1}, {"two", 2}} +``` + +## Implicit conversions + +By default, a JSON value implicitly converts to a compatible C++ type, so the explicit `get` call can often be omitted: + +``` +json j = "Hello"; +std::string s = j; // implicit conversion, same as j.get() +``` + +Implicit conversions are convenient but can be surprising (for example, in overload resolution or with `auto`). They can be disabled by defining [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) to `0`, which forces the explicit `get` form and can catch unintended conversions at compile time. + +Conversions do not range-check numbers + +Just like C++ itself, the `get` family performs numeric conversions without range checks — retrieving a floating-point value as an integer truncates it, and narrowing conversions may overflow. See [number conversion](https://json.nlohmann.me/features/types/number_handling/#number-conversion) for details and how to guard against it. + +## Putting values in + +The reverse direction works the same way: assigning or constructing a `json` from a C++ value converts it to JSON. + +``` +std::vector numbers = {1, 2, 3}; +json j = numbers; // [1,2,3] +``` + +## Your own types + +The conversions above are built in for standard types. To make the same syntax work for **your own** types, provide `to_json`/`from_json` functions (or use one of the convenience macros). This is described in detail on the [arbitrary types conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) page. Enums can be mapped to strings as described in [specializing enum conversion](https://json.nlohmann.me/features/enum_conversion/index.md). + +## See also + +- [`get`](https://json.nlohmann.me/api/basic_json/get/index.md) - get a copy converted to a given type +- [`get_to`](https://json.nlohmann.me/api/basic_json/get_to/index.md) - convert into an existing variable +- [`get_ref`](https://json.nlohmann.me/api/basic_json/get_ref/index.md) / [`get_ptr`](https://json.nlohmann.me/api/basic_json/get_ptr/index.md) - access the stored value without copying +- [Arbitrary types conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) - support your own types +- [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) - toggle implicit conversions diff --git a/features/creating_values.md b/features/creating_values.md new file mode 100644 index 000000000..fc35b3401 --- /dev/null +++ b/features/creating_values.md @@ -0,0 +1,103 @@ +# Creating JSON values + +There are several ways to create a JSON value in memory. This page gives an overview; to read a value from JSON text +instead, see [parsing](parsing/index.md). + +## From C++ values + +Any value of a supported C++ type can be assigned to or used to construct a `json`: + +```cpp +json j_number = 42; +json j_float = 3.141; +json j_string = "Hello"; +json j_boolean = true; +json j_null = nullptr; +json j_vector = std::vector{1, 2, 3}; // array +``` + +See [converting values](conversions.md) for the full set of supported types. + +## With initializer lists + +Objects and arrays can be written concisely with brace-enclosed initializer lists: + +```cpp +// an array +json array = {1, 2, 3, 4}; + +// an object (a list of key/value pairs) +json object = { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + {"list", {1, 0, 2}}, + {"object", {{"currency", "USD"}, {"value", 42.99}}} +}; +``` + +The library decides between an array and an object based on the content: a list whose elements are all two-element lists +with a string as the first element is treated as an object, everything else as an array. + +!!! warning "Ambiguous cases: `#!cpp {}` vs. `#!cpp []`" + + Because the same `#!cpp {}` syntax is used for both arrays and objects, some cases are ambiguous. To force a + particular type, use the explicit factory functions [`json::array`](../api/basic_json/array.md) and + [`json::object`](../api/basic_json/object.md): + + ```cpp + json empty_array_explicit = json::array(); // [] + json empty_object_explicit = json::object(); // {} + + // a JSON array with one object, not an object with one member + json array_of_objects = json::array({{"key", "value"}}); // [{"key":"value"}] + ``` + + Related to this, single-element brace initialization such as `#!cpp json j{value};` wraps the element in a + single-element **array** by default, and its behavior even differs between compilers. See the + [FAQ](../home/faq.md#brace-initialization-yields-arrays) for details and the opt-in + [`JSON_BRACE_INIT_COPY_SEMANTICS`](../api/macros/json_brace_init_copy_semantics.md) macro. + +## Building incrementally + +A value can also be built up piece by piece. Accessing a non-existing object key or array index with +[`operator[]`](element_access/unchecked_access.md) creates the element on the fly: + +```cpp +json j; // null +j["answer"]["everything"] = 42; // becomes an object +j["list"] = {1, 0, 2}; +j["list"].push_back(3); // [1,0,2,3] +``` + +See [modifying values](modifying_values.md) for [`push_back`](../api/basic_json/push_back.md), +[`emplace`](../api/basic_json/emplace.md), and related functions. + +## With the `_json` literal + +The `_json` [user-defined literal](../api/operator_literal_json.md) parses a string at the call site and is a +convenient way to write a JSON value inline: + +??? example + + ```cpp + --8<-- "examples/operator_literal_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_literal_json.output" + ``` + +Note this **parses** the string, so `#!cpp "42"_json` is the number `#!cpp 42`, whereas `#!cpp json("42")` is the JSON +string `#!json "42"`. + +## See also + +- [`basic_json` constructors](../api/basic_json/basic_json.md) - all ways to construct a value +- [`array`](../api/basic_json/array.md) / [`object`](../api/basic_json/object.md) - force array or object type +- [`operator""_json`](../api/operator_literal_json.md) - the `_json` literal +- [Converting values](conversions.md) - which C++ types can be used +- [Parsing](parsing/index.md) - create a value from JSON text diff --git a/features/creating_values/index.html b/features/creating_values/index.html index 096aa4e3b..0fe264e40 100644 --- a/features/creating_values/index.html +++ b/features/creating_values/index.html @@ -42,4 +42,4 @@ "answer": 42, "hello": "world" } -

    Note this parses the string, so "42"_json is the number 42, whereas json("42") is the JSON string "42".

    See also

    \ No newline at end of file +

    Note this parses the string, so "42"_json is the number 42, whereas json("42") is the JSON string "42".

    See also

    \ No newline at end of file diff --git a/features/creating_values/index.md b/features/creating_values/index.md new file mode 100644 index 000000000..0f6317a2d --- /dev/null +++ b/features/creating_values/index.md @@ -0,0 +1,107 @@ +# Creating JSON values + +There are several ways to create a JSON value in memory. This page gives an overview; to read a value from JSON text instead, see [parsing](https://json.nlohmann.me/features/parsing/index.md). + +## From C++ values + +Any value of a supported C++ type can be assigned to or used to construct a `json`: + +``` +json j_number = 42; +json j_float = 3.141; +json j_string = "Hello"; +json j_boolean = true; +json j_null = nullptr; +json j_vector = std::vector{1, 2, 3}; // array +``` + +See [converting values](https://json.nlohmann.me/features/conversions/index.md) for the full set of supported types. + +## With initializer lists + +Objects and arrays can be written concisely with brace-enclosed initializer lists: + +``` +// an array +json array = {1, 2, 3, 4}; + +// an object (a list of key/value pairs) +json object = { + {"pi", 3.141}, + {"happy", true}, + {"name", "Niels"}, + {"nothing", nullptr}, + {"list", {1, 0, 2}}, + {"object", {{"currency", "USD"}, {"value", 42.99}}} +}; +``` + +The library decides between an array and an object based on the content: a list whose elements are all two-element lists with a string as the first element is treated as an object, everything else as an array. + +Ambiguous cases: `{}` vs. `[]` + +Because the same `{}` syntax is used for both arrays and objects, some cases are ambiguous. To force a particular type, use the explicit factory functions [`json::array`](https://json.nlohmann.me/api/basic_json/array/index.md) and [`json::object`](https://json.nlohmann.me/api/basic_json/object/index.md): + +``` +json empty_array_explicit = json::array(); // [] +json empty_object_explicit = json::object(); // {} + +// a JSON array with one object, not an object with one member +json array_of_objects = json::array({{"key", "value"}}); // [{"key":"value"}] +``` + +Related to this, single-element brace initialization such as `json j{value};` wraps the element in a single-element **array** by default, and its behavior even differs between compilers. See the [FAQ](https://json.nlohmann.me/home/faq/#brace-initialization-yields-arrays) for details and the opt-in [`JSON_BRACE_INIT_COPY_SEMANTICS`](https://json.nlohmann.me/api/macros/json_brace_init_copy_semantics/index.md) macro. + +## Building incrementally + +A value can also be built up piece by piece. Accessing a non-existing object key or array index with [`operator[]`](https://json.nlohmann.me/features/element_access/unchecked_access/index.md) creates the element on the fly: + +``` +json j; // null +j["answer"]["everything"] = 42; // becomes an object +j["list"] = {1, 0, 2}; +j["list"].push_back(3); // [1,0,2,3] +``` + +See [modifying values](https://json.nlohmann.me/features/modifying_values/index.md) for [`push_back`](https://json.nlohmann.me/api/basic_json/push_back/index.md), [`emplace`](https://json.nlohmann.me/api/basic_json/emplace/index.md), and related functions. + +## With the `_json` literal + +The `_json` [user-defined literal](https://json.nlohmann.me/api/operator_literal_json/index.md) parses a string at the call site and is a convenient way to write a JSON value inline: + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + json j = R"( {"hello": "world", "answer": 42} )"_json; + + std::cout << std::setw(2) << j << '\n'; +} +``` + +Output: + +``` +{ + "answer": 42, + "hello": "world" +} +``` + +Note this **parses** the string, so `"42"_json` is the number `42`, whereas `json("42")` is the JSON string `"42"`. + +## See also + +- [`basic_json` constructors](https://json.nlohmann.me/api/basic_json/basic_json/index.md) - all ways to construct a value +- [`array`](https://json.nlohmann.me/api/basic_json/array/index.md) / [`object`](https://json.nlohmann.me/api/basic_json/object/index.md) - force array or object type +- [`operator""_json`](https://json.nlohmann.me/api/operator_literal_json/index.md) - the `_json` literal +- [Converting values](https://json.nlohmann.me/features/conversions/index.md) - which C++ types can be used +- [Parsing](https://json.nlohmann.me/features/parsing/index.md) - create a value from JSON text diff --git a/features/element_access.md b/features/element_access.md new file mode 100644 index 000000000..0b39547ec --- /dev/null +++ b/features/element_access.md @@ -0,0 +1,9 @@ +# Element Access + +There are many ways elements in a JSON value can be accessed: + +- unchecked access via [`operator[]`](unchecked_access.md) +- checked access via [`at`](checked_access.md) +- access with default value via [`value`](default_value.md) +- iterators +- JSON pointers diff --git a/features/element_access/checked_access.md b/features/element_access/checked_access.md new file mode 100644 index 000000000..1fb65e53b --- /dev/null +++ b/features/element_access/checked_access.md @@ -0,0 +1,91 @@ +# Checked access: at + +## Overview + +The [`at`](../../api/basic_json/at.md) member function performs checked access; that is, it returns a reference to the +desired value if it exists and throws a [`basic_json::out_of_range` exception](../../home/exceptions.md#out-of-range) +otherwise. + +??? example "Read access" + + Consider the following JSON value: + + ```json + { + "name": "Mary Smith", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + + Assume the value is parsed to a `json` variable `j`. + + | expression | value | + |-------------------------------|------------------------------------------------------------------------------| + | `#!cpp j` | `#!json {"name": "Mary Smith", "age": 42, "hobbies": ["hiking", "reading"]}` | + | `#!cpp j.at("name")` | `#!json "Mary Smith"` | + | `#!cpp j.at("age")` | `#!json 42` | + | `#!cpp j.at("hobbies")` | `#!json ["hiking", "reading"]` | + | `#!cpp j.at("hobbies").at(0)` | `#!json "hiking"` | + | `#!cpp j.at("hobbies").at(1)` | `#!json "reading"` | + +The return value is a reference, so it can be used to modify the original value. + +??? example "Write access" + + ```cpp + j.at("name") = "John Smith"; + ``` + + This code produces the following JSON value: + + ```json + { + "name": "John Smith", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + +When accessing an invalid index (i.e., an index greater than or equal to the array size) or the passed object key is +non-existing, an exception is thrown. + +??? example "Accessing via invalid index or missing key" + + ```cpp + j.at("hobbies").at(3) = "cooking"; + ``` + + This code produces the following exception: + + ``` + [json.exception.out_of_range.401] array index 3 is out of range + ``` + + When [extended diagnostic messages](../../home/exceptions.md#extended-diagnostic-messages) are enabled by + defining [`JSON_DIAGNOSTICS`](../../api/macros/json_diagnostics.md), the exception further gives information where + the key or index is missing or out of range. + + ``` + [json.exception.out_of_range.401] (/hobbies) array index 3 is out of range + ``` + +## Notes + + +!!! failure "Exceptions" + + - [`at`](../../api/basic_json/at.md) can only be used with objects (with a string argument) or with arrays (with a + numeric argument). For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error304) + is thrown. + - [`basic_json::out_of_range` exception](../../home/exceptions.md#out-of-range) exceptions are thrown if the + provided key is not found in an object or the provided index is invalid. + +## Summary + +| scenario | non-const value | const value | +|-----------------------------------|------------------------------------------------|------------------------------------------------| +| access to existing object key | reference to existing value is returned | const reference to existing value is returned | +| access to valid array index | reference to existing value is returned | const reference to existing value is returned | +| access to non-existing object key | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown | +| access to invalid array index | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown | diff --git a/features/element_access/checked_access/index.html b/features/element_access/checked_access/index.html index 209d8ee85..c7ebe26ad 100644 --- a/features/element_access/checked_access/index.html +++ b/features/element_access/checked_access/index.html @@ -12,4 +12,4 @@

    When accessing an invalid index (i.e., an index greater than or equal to the array size) or the passed object key is non-existing, an exception is thrown.

    Accessing via invalid index or missing key
    j.at("hobbies").at(3) = "cooking";
     

    This code produces the following exception:

    [json.exception.out_of_range.401] array index 3 is out of range
     

    When extended diagnostic messages are enabled by defining JSON_DIAGNOSTICS, the exception further gives information where the key or index is missing or out of range.

    [json.exception.out_of_range.401] (/hobbies) array index 3 is out of range
    -

    Notes

    Exceptions

    • at can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.
    • basic_json::out_of_range exception exceptions are thrown if the provided key is not found in an object or the provided index is invalid.

    Summary

    scenario non-const value const value
    access to existing object key reference to existing value is returned const reference to existing value is returned
    access to valid array index reference to existing value is returned const reference to existing value is returned
    access to non-existing object key basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown
    access to invalid array index basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown
    \ No newline at end of file +

    Notes

    Exceptions

    • at can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.
    • basic_json::out_of_range exception exceptions are thrown if the provided key is not found in an object or the provided index is invalid.

    Summary

    scenario non-const value const value
    access to existing object key reference to existing value is returned const reference to existing value is returned
    access to valid array index reference to existing value is returned const reference to existing value is returned
    access to non-existing object key basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown
    access to invalid array index basic_json::out_of_range exception is thrown basic_json::out_of_range exception is thrown
    \ No newline at end of file diff --git a/features/element_access/checked_access/index.md b/features/element_access/checked_access/index.md new file mode 100644 index 000000000..6111b1545 --- /dev/null +++ b/features/element_access/checked_access/index.md @@ -0,0 +1,82 @@ +# Checked access: at + +## Overview + +The [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) member function performs checked access; that is, it returns a reference to the desired value if it exists and throws a [`basic_json::out_of_range` exception](https://json.nlohmann.me/home/exceptions/#out-of-range) otherwise. + +Read access + +Consider the following JSON value: + +``` +{ + "name": "Mary Smith", + "age": 42, + "hobbies": ["hiking", "reading"] +} +``` + +Assume the value is parsed to a `json` variable `j`. + +| expression | value | +| ----------------------- | --------------------------------------------------------------------- | +| `j` | `{"name": "Mary Smith", "age": 42, "hobbies": ["hiking", "reading"]}` | +| `j.at("name")` | `"Mary Smith"` | +| `j.at("age")` | `42` | +| `j.at("hobbies")` | `["hiking", "reading"]` | +| `j.at("hobbies").at(0)` | `"hiking"` | +| `j.at("hobbies").at(1)` | `"reading"` | + +The return value is a reference, so it can be used to modify the original value. + +Write access + +``` +j.at("name") = "John Smith"; +``` + +This code produces the following JSON value: + +``` +{ + "name": "John Smith", + "age": 42, + "hobbies": ["hiking", "reading"] +} +``` + +When accessing an invalid index (i.e., an index greater than or equal to the array size) or the passed object key is non-existing, an exception is thrown. + +Accessing via invalid index or missing key + +``` +j.at("hobbies").at(3) = "cooking"; +``` + +This code produces the following exception: + +``` +[json.exception.out_of_range.401] array index 3 is out of range +``` + +When [extended diagnostic messages](https://json.nlohmann.me/home/exceptions/#extended-diagnostic-messages) are enabled by defining [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md), the exception further gives information where the key or index is missing or out of range. + +``` +[json.exception.out_of_range.401] (/hobbies) array index 3 is out of range +``` + +## Notes + +Exceptions + +- [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a [`basic_json::type_error`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error304) is thrown. +- [`basic_json::out_of_range` exception](https://json.nlohmann.me/home/exceptions/#out-of-range) exceptions are thrown if the provided key is not found in an object or the provided index is invalid. + +## Summary + +| scenario | non-const value | const value | +| --------------------------------- | ---------------------------------------------- | ---------------------------------------------- | +| access to existing object key | reference to existing value is returned | const reference to existing value is returned | +| access to valid array index | reference to existing value is returned | const reference to existing value is returned | +| access to non-existing object key | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown | +| access to invalid array index | `basic_json::out_of_range` exception is thrown | `basic_json::out_of_range` exception is thrown | diff --git a/features/element_access/default_value.md b/features/element_access/default_value.md new file mode 100644 index 000000000..4f714a287 --- /dev/null +++ b/features/element_access/default_value.md @@ -0,0 +1,64 @@ +# Access with default value: value + +## Overview + +In many situations, such as configuration files, missing values are not exceptional, but may be treated as if a default +value was present. For this case, use [`value(key, default_value)`](../../api/basic_json/value.md) which takes the key +you want to access and a default value in case there is no value stored with that key. + +## Example + +??? example + + Consider the following JSON value: + + ```json + { + "logOutput": "result.log", + "append": true + } + ``` + + Assume the value is parsed to a `json` variable `j`. + + | expression | value | + |---------------------------------------------|------------------------------------------------------| + | `#!cpp j` | `#!json {"logOutput": "result.log", "append": true}` | + | `#!cpp j.value("logOutput", "logfile.log")` | `#!json "result.log"` | + | `#!cpp j.value("append", true)` | `#!json true` | + | `#!cpp j.value("append", false)` | `#!json true` | + | `#!cpp j.value("logLevel", "verbose")` | `#!json "verbose"` | + +## Notes + +!!! failure "Exceptions" + + - With string keys, `value` can only be used with objects. For other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error306) is thrown. + - With JSON Pointers, `value` can be used with both objects and arrays. For other types (null, boolean, number, string), a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error306) is thrown. + +!!! warning "Return type" + + The value function is a template, and the return type of the function is determined by the type of the provided + default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit + unsigned integer. We get exactly that value when using [`operator[]`](../../api/basic_json/operator[].md). However, + when we call `value` and provide `#!c 0` as default value, then `#!c -1` is returned. This occurs, because `#!c 0` + has type `#!c int` which overflows when handling the value `#!c 18446744073709551615`. + + To address this issue, either provide a correctly typed default value or use the template parameter to specify the + desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default + value is not used as the return value. + + ```cpp + --8<-- "examples/value__return_type.cpp" + ``` + + Output: + + ```json + --8<-- "examples/value__return_type.output" + ``` + +## See also + +- [`value`](../../api/basic_json/value.md) for access with default value +- documentation on [checked access](checked_access.md) diff --git a/features/element_access/default_value/index.html b/features/element_access/default_value/index.html index 6a49dd55c..1454cedb7 100644 --- a/features/element_access/default_value/index.html +++ b/features/element_access/default_value/index.html @@ -20,4 +20,4 @@ default value (int): -1 default value (uint64_t): 18446744073709551615 explicit return value type: 18446744073709551615 -

    See also

    \ No newline at end of file +

    See also

    \ No newline at end of file diff --git a/features/element_access/default_value/index.md b/features/element_access/default_value/index.md new file mode 100644 index 000000000..889203bfa --- /dev/null +++ b/features/element_access/default_value/index.md @@ -0,0 +1,72 @@ +# Access with default value: value + +## Overview + +In many situations, such as configuration files, missing values are not exceptional, but may be treated as if a default value was present. For this case, use [`value(key, default_value)`](https://json.nlohmann.me/api/basic_json/value/index.md) which takes the key you want to access and a default value in case there is no value stored with that key. + +## Example + +Example + +Consider the following JSON value: + +``` +{ + "logOutput": "result.log", + "append": true +} +``` + +Assume the value is parsed to a `json` variable `j`. + +| expression | value | +| ------------------------------------- | --------------------------------------------- | +| `j` | `{"logOutput": "result.log", "append": true}` | +| `j.value("logOutput", "logfile.log")` | `"result.log"` | +| `j.value("append", true)` | `true` | +| `j.value("append", false)` | `true` | +| `j.value("logLevel", "verbose")` | `"verbose"` | + +## Notes + +Exceptions + +- With string keys, `value` can only be used with objects. For other types, a [`basic_json::type_error`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error306) is thrown. +- With JSON Pointers, `value` can be used with both objects and arrays. For other types (null, boolean, number, string), a [`basic_json::type_error`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error306) is thrown. + +Return type + +The value function is a template, and the return type of the function is determined by the type of the provided default value unless otherwise specified. This can have unexpected effects. In the example below, we store a 64-bit unsigned integer. We get exactly that value when using [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md). However, when we call `value` and provide `0` as default value, then `-1` is returned. This occurs, because `0` has type `int` which overflows when handling the value `18446744073709551615`. + +To address this issue, either provide a correctly typed default value or use the template parameter to specify the desired return type. Note that this issue occurs even when a value is stored at the provided key, and the default value is not used as the return value. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j = json::parse(R"({"uint64": 18446744073709551615})"); + + std::cout << "operator[]: " << j["uint64"] << '\n' + << "default value (int): " << j.value("uint64", 0) << '\n' + << "default value (uint64_t): " << j.value("uint64", std::uint64_t(0)) << '\n' + << "explicit return value type: " << j.value("uint64", 0) << '\n'; +} +``` + +Output: + +``` +operator[]: 18446744073709551615 +default value (int): -1 +default value (uint64_t): 18446744073709551615 +explicit return value type: 18446744073709551615 +``` + +## See also + +- [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) for access with default value +- documentation on [checked access](https://json.nlohmann.me/features/element_access/checked_access/index.md) diff --git a/features/element_access/index.html b/features/element_access/index.html index b0199c146..b0d5e8377 100644 --- a/features/element_access/index.html +++ b/features/element_access/index.html @@ -1 +1 @@ - Element Access - JSON for Modern C++

    Element Access

    There are many ways elements in a JSON value can be accessed:

    • unchecked access via operator[]
    • checked access via at
    • access with default value via value
    • iterators
    • JSON pointers
    \ No newline at end of file + Element Access - JSON for Modern C++

    Element Access

    There are many ways elements in a JSON value can be accessed:

    • unchecked access via operator[]
    • checked access via at
    • access with default value via value
    • iterators
    • JSON pointers
    \ No newline at end of file diff --git a/features/element_access/index.md b/features/element_access/index.md new file mode 100644 index 000000000..382640cf9 --- /dev/null +++ b/features/element_access/index.md @@ -0,0 +1,9 @@ +# Element Access + +There are many ways elements in a JSON value can be accessed: + +- unchecked access via [`operator[]`](https://json.nlohmann.me/features/element_access/unchecked_access/index.md) +- checked access via [`at`](https://json.nlohmann.me/features/element_access/checked_access/index.md) +- access with default value via [`value`](https://json.nlohmann.me/features/element_access/default_value/index.md) +- iterators +- JSON pointers diff --git a/features/element_access/unchecked_access.md b/features/element_access/unchecked_access.md new file mode 100644 index 000000000..f2de067d3 --- /dev/null +++ b/features/element_access/unchecked_access.md @@ -0,0 +1,112 @@ +# Unchecked access: operator[] + +## Overview + +Elements in a JSON object and a JSON array can be accessed via [`operator[]`](../../api/basic_json/operator%5B%5D.md) +similar to a `#!cpp std::map` and a `#!cpp std::vector`, respectively. + +??? example "Read access" + + Consider the following JSON value: + + ```json + { + "name": "Mary Smith", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + + Assume the value is parsed to a `json` variable `j`. + + | expression | value | + |-------------------------|------------------------------------------------------------------------------| + | `#!cpp j` | `#!json {"name": "Mary Smith", "age": 42, "hobbies": ["hiking", "reading"]}` | + | `#!cpp j["name"]` | `#!json "Mary Smith"` | + | `#!cpp j["age"]` | `#!json 42` | + | `#!cpp j["hobbies"]` | `#!json ["hiking", "reading"]` | + | `#!cpp j["hobbies"][0]` | `#!json "hiking"` | + | `#!cpp j["hobbies"][1]` | `#!json "reading"` | + +The return value is a reference, so it can modify the original value. In case the passed object key is non-existing, a +`#!json null` value is inserted which can immediately be overwritten. + +??? example "Write access" + + ```cpp + j["name"] = "John Smith"; + j["maidenName"] = "Jones"; + ``` + + This code produces the following JSON value: + + ```json + { + "name": "John Smith", + "maidenName": "Jones", + "age": 42, + "hobbies": ["hiking", "reading"] + } + ``` + +When accessing an invalid index (i.e., an index greater than or equal to the array size), the JSON array is resized such +that the passed index is the new maximal index. Intermediate values are filled with `#!json null`. + +??? example "Filling up arrays with `#!json null` values" + + ```cpp + j["hobbies"][0] = "running"; + j["hobbies"][3] = "cooking"; + ``` + + This code produces the following JSON value: + + ```json + { + "name": "John Smith", + "maidenName": "Jones", + "age": 42, + "hobbies": ["running", "reading", null, "cooking"] + } + ``` + +## Notes + +!!! info "Design rationale" + + The library behaves differently to `#!cpp std::vector` and `#!cpp std::map`: + + - `#!cpp std::vector::operator[]` never inserts a new element. + - `#!cpp std::map::operator[]` is not available for const values. + + The type `#!cpp json` wraps all JSON value types. It would be impossible to remove + [`operator[]`](../../api/basic_json/operator%5B%5D.md) for const objects. At the same time, inserting elements for + non-const objects is really convenient as it avoids awkward `insert` calls. To this end, we decided to have an + inserting non-const behavior for both arrays and objects. + +!!! info + + The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no + exception is thrown. + +!!! danger + + - It is **undefined behavior** to access a const object with a non-existing key. + - It is **undefined behavior** to access a const array with an invalid index. + - In debug mode, an **assertion** will fire in both cases. You can disable assertions by defining the preprocessor + symbol `#!cpp NDEBUG` or redefine the macro [`JSON_ASSERT(x)`](../macros.md#json_assertx). See the documentation + on [runtime assertions](../assertions.md) for more information. + +!!! failure "Exceptions" + + `operator[]` can only be used with objects (with a string argument) or with arrays (with a numeric argument). For + other types, a [`basic_json::type_error`](../../home/exceptions.md#jsonexceptiontype_error305) is thrown. + +## Summary + +| scenario | non-const value | const value | +|-----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------| +| access to existing object key | reference to existing value is returned | const reference to existing value is returned | +| access to valid array index | reference to existing value is returned | const reference to existing value is returned | +| access to non-existing object key | reference to newly inserted `#!json null` value is returned | **undefined behavior**; [runtime assertion](../assertions.md) in debug mode | +| access to invalid array index | reference to newly inserted `#!json null` value is returned; any index between previous maximal index and passed index are filled with `#!json null` | **undefined behavior**; [runtime assertion](../assertions.md) in debug mode | diff --git a/features/element_access/unchecked_access/index.html b/features/element_access/unchecked_access/index.html index 8eb1dbe47..5c64801c9 100644 --- a/features/element_access/unchecked_access/index.html +++ b/features/element_access/unchecked_access/index.html @@ -19,4 +19,4 @@ "age": 42, "hobbies": ["running", "reading", null, "cooking"] } -

    Notes

    Design rationale

    The library behaves differently to std::vector and std::map:

    • std::vector::operator[] never inserts a new element.
    • std::map::operator[] is not available for const values.

    The type json wraps all JSON value types. It would be impossible to remove operator[] for const objects. At the same time, inserting elements for non-const objects is really convenient as it avoids awkward insert calls. To this end, we decided to have an inserting non-const behavior for both arrays and objects.

    Info

    The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no exception is thrown.

    Danger

    • It is undefined behavior to access a const object with a non-existing key.
    • It is undefined behavior to access a const array with an invalid index.
    • In debug mode, an assertion will fire in both cases. You can disable assertions by defining the preprocessor symbol NDEBUG or redefine the macro JSON_ASSERT(x). See the documentation on runtime assertions for more information.

    Exceptions

    operator[] can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.

    Summary

    scenario non-const value const value
    access to existing object key reference to existing value is returned const reference to existing value is returned
    access to valid array index reference to existing value is returned const reference to existing value is returned
    access to non-existing object key reference to newly inserted null value is returned undefined behavior; runtime assertion in debug mode
    access to invalid array index reference to newly inserted null value is returned; any index between previous maximal index and passed index are filled with null undefined behavior; runtime assertion in debug mode
    \ No newline at end of file +

    Notes

    Design rationale

    The library behaves differently to std::vector and std::map:

    • std::vector::operator[] never inserts a new element.
    • std::map::operator[] is not available for const values.

    The type json wraps all JSON value types. It would be impossible to remove operator[] for const objects. At the same time, inserting elements for non-const objects is really convenient as it avoids awkward insert calls. To this end, we decided to have an inserting non-const behavior for both arrays and objects.

    Info

    The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no exception is thrown.

    Danger

    • It is undefined behavior to access a const object with a non-existing key.
    • It is undefined behavior to access a const array with an invalid index.
    • In debug mode, an assertion will fire in both cases. You can disable assertions by defining the preprocessor symbol NDEBUG or redefine the macro JSON_ASSERT(x). See the documentation on runtime assertions for more information.

    Exceptions

    operator[] can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a basic_json::type_error is thrown.

    Summary

    scenario non-const value const value
    access to existing object key reference to existing value is returned const reference to existing value is returned
    access to valid array index reference to existing value is returned const reference to existing value is returned
    access to non-existing object key reference to newly inserted null value is returned undefined behavior; runtime assertion in debug mode
    access to invalid array index reference to newly inserted null value is returned; any index between previous maximal index and passed index are filled with null undefined behavior; runtime assertion in debug mode
    \ No newline at end of file diff --git a/features/element_access/unchecked_access/index.md b/features/element_access/unchecked_access/index.md new file mode 100644 index 000000000..83cd216a4 --- /dev/null +++ b/features/element_access/unchecked_access/index.md @@ -0,0 +1,102 @@ +# Unchecked access: operator[] + +## Overview + +Elements in a JSON object and a JSON array can be accessed via [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) similar to a `std::map` and a `std::vector`, respectively. + +Read access + +Consider the following JSON value: + +``` +{ + "name": "Mary Smith", + "age": 42, + "hobbies": ["hiking", "reading"] +} +``` + +Assume the value is parsed to a `json` variable `j`. + +| expression | value | +| ----------------- | --------------------------------------------------------------------- | +| `j` | `{"name": "Mary Smith", "age": 42, "hobbies": ["hiking", "reading"]}` | +| `j["name"]` | `"Mary Smith"` | +| `j["age"]` | `42` | +| `j["hobbies"]` | `["hiking", "reading"]` | +| `j["hobbies"][0]` | `"hiking"` | +| `j["hobbies"][1]` | `"reading"` | + +The return value is a reference, so it can modify the original value. In case the passed object key is non-existing, a `null` value is inserted which can immediately be overwritten. + +Write access + +``` +j["name"] = "John Smith"; +j["maidenName"] = "Jones"; +``` + +This code produces the following JSON value: + +``` +{ + "name": "John Smith", + "maidenName": "Jones", + "age": 42, + "hobbies": ["hiking", "reading"] +} +``` + +When accessing an invalid index (i.e., an index greater than or equal to the array size), the JSON array is resized such that the passed index is the new maximal index. Intermediate values are filled with `null`. + +Filling up arrays with `null` values + +``` +j["hobbies"][0] = "running"; +j["hobbies"][3] = "cooking"; +``` + +This code produces the following JSON value: + +``` +{ + "name": "John Smith", + "maidenName": "Jones", + "age": 42, + "hobbies": ["running", "reading", null, "cooking"] +} +``` + +## Notes + +Design rationale + +The library behaves differently to `std::vector` and `std::map`: + +- `std::vector::operator[]` never inserts a new element. +- `std::map::operator[]` is not available for const values. + +The type `json` wraps all JSON value types. It would be impossible to remove [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) for const objects. At the same time, inserting elements for non-const objects is really convenient as it avoids awkward `insert` calls. To this end, we decided to have an inserting non-const behavior for both arrays and objects. + +Info + +The access is unchecked. In case the passed object key does not exist or the passed array index is invalid, no exception is thrown. + +Danger + +- It is **undefined behavior** to access a const object with a non-existing key. +- It is **undefined behavior** to access a const array with an invalid index. +- In debug mode, an **assertion** will fire in both cases. You can disable assertions by defining the preprocessor symbol `NDEBUG` or redefine the macro [`JSON_ASSERT(x)`](https://json.nlohmann.me/features/macros/#json_assertx). See the documentation on [runtime assertions](https://json.nlohmann.me/features/assertions/index.md) for more information. + +Exceptions + +`operator[]` can only be used with objects (with a string argument) or with arrays (with a numeric argument). For other types, a [`basic_json::type_error`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error305) is thrown. + +## Summary + +| scenario | non-const value | const value | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| access to existing object key | reference to existing value is returned | const reference to existing value is returned | +| access to valid array index | reference to existing value is returned | const reference to existing value is returned | +| access to non-existing object key | reference to newly inserted `null` value is returned | **undefined behavior**; [runtime assertion](https://json.nlohmann.me/features/assertions/index.md) in debug mode | +| access to invalid array index | reference to newly inserted `null` value is returned; any index between previous maximal index and passed index are filled with `null` | **undefined behavior**; [runtime assertion](https://json.nlohmann.me/features/assertions/index.md) in debug mode | diff --git a/features/enum_conversion.md b/features/enum_conversion.md new file mode 100644 index 000000000..d75d6e112 --- /dev/null +++ b/features/enum_conversion.md @@ -0,0 +1,62 @@ +# Specializing enum conversion + +By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If +the integer values of any enum values are changed after data using those enum values has been serialized to JSON, then +deserializing that JSON would result in a different enum value being restored, or the value not being found at all. + +It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below: + +```cpp +// example enum type declaration +enum TaskState { + TS_STOPPED, + TS_RUNNING, + TS_COMPLETED, + TS_INVALID=-1, +}; + +// map TaskState values to JSON as strings +NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, { + {TS_INVALID, nullptr}, + {TS_STOPPED, "stopped"}, + {TS_RUNNING, "running"}, + {TS_COMPLETED, "completed"}, +}) +``` + +The [`NLOHMANN_JSON_SERIALIZE_ENUM()` macro](../api/macros/nlohmann_json_serialize_enum.md) declares a set of +`to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code. + +## Usage + +```cpp +// enum to JSON as string +json j = TS_STOPPED; +assert(j == "stopped"); + +// json string to enum +json j3 = "running"; +assert(j3.get() == TS_RUNNING); + +// undefined json value to enum (where the first map entry above is the default) +json jPi = 3.14; +assert(jPi.get() == TS_INVALID ); +``` + +## Notes + +Just as in [Arbitrary Type Conversions](arbitrary_types.md) above, + +- [`NLOHMANN_JSON_SERIALIZE_ENUM()`](../api/macros/nlohmann_json_serialize_enum.md) MUST be declared in your enum type's + namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to + integer serialization. +- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions. + +Other Important points: + +- When using `get()`, undefined JSON values will default to the first pair specified in your map. Select this + default pair carefully. If you desire an exception in this circumstance use [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT()`](../api/macros/nlohmann_json_serialize_enum_strict.md) + which behaves identically except for throwing an exception on unrecognized values. +- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the + map will be returned when converting to or from JSON. +- To disable the default serialization of enumerators as integers and force a compiler error instead, see [`JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md). diff --git a/features/enum_conversion/index.html b/features/enum_conversion/index.html index d06bfa47f..df2379d45 100644 --- a/features/enum_conversion/index.html +++ b/features/enum_conversion/index.html @@ -24,4 +24,4 @@ // undefined json value to enum (where the first map entry above is the default) json jPi = 3.14; assert(jPi.get<TaskState>() == TS_INVALID ); -

    Notes

    Just as in Arbitrary Type Conversions above,

    • NLOHMANN_JSON_SERIALIZE_ENUM() MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to integer serialization.
    • It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.

    Other Important points:

    • When using get<ENUM_TYPE>(), undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. If you desire an exception in this circumstance use NLOHMANN_JSON_SERIALIZE_ENUM_STRICT() which behaves identically except for throwing an exception on unrecognized values.
    • If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
    • To disable the default serialization of enumerators as integers and force a compiler error instead, see JSON_DISABLE_ENUM_SERIALIZATION.
    \ No newline at end of file +

    Notes

    Just as in Arbitrary Type Conversions above,

    • NLOHMANN_JSON_SERIALIZE_ENUM() MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to integer serialization.
    • It MUST be available (e.g., proper headers must be included) everywhere you use the conversions.

    Other Important points:

    • When using get<ENUM_TYPE>(), undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. If you desire an exception in this circumstance use NLOHMANN_JSON_SERIALIZE_ENUM_STRICT() which behaves identically except for throwing an exception on unrecognized values.
    • If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON.
    • To disable the default serialization of enumerators as integers and force a compiler error instead, see JSON_DISABLE_ENUM_SERIALIZATION.
    \ No newline at end of file diff --git a/features/enum_conversion/index.md b/features/enum_conversion/index.md new file mode 100644 index 000000000..95e99dda2 --- /dev/null +++ b/features/enum_conversion/index.md @@ -0,0 +1,54 @@ +# Specializing enum conversion + +By default, enum values are serialized to JSON as integers. In some cases, this could result in undesired behavior. If the integer values of any enum values are changed after data using those enum values has been serialized to JSON, then deserializing that JSON would result in a different enum value being restored, or the value not being found at all. + +It is possible to more precisely specify how a given enum is mapped to and from JSON as shown below: + +``` +// example enum type declaration +enum TaskState { + TS_STOPPED, + TS_RUNNING, + TS_COMPLETED, + TS_INVALID=-1, +}; + +// map TaskState values to JSON as strings +NLOHMANN_JSON_SERIALIZE_ENUM( TaskState, { + {TS_INVALID, nullptr}, + {TS_STOPPED, "stopped"}, + {TS_RUNNING, "running"}, + {TS_COMPLETED, "completed"}, +}) +``` + +The [`NLOHMANN_JSON_SERIALIZE_ENUM()` macro](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) declares a set of `to_json()` / `from_json()` functions for type `TaskState` while avoiding repetition and boilerplate serialization code. + +## Usage + +``` +// enum to JSON as string +json j = TS_STOPPED; +assert(j == "stopped"); + +// json string to enum +json j3 = "running"; +assert(j3.get() == TS_RUNNING); + +// undefined json value to enum (where the first map entry above is the default) +json jPi = 3.14; +assert(jPi.get() == TS_INVALID ); +``` + +## Notes + +Just as in [Arbitrary Type Conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) above, + +- [`NLOHMANN_JSON_SERIALIZE_ENUM()`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) MUST be declared in your enum type's namespace (which can be the global namespace), or the library will not be able to locate it, and it will default to integer serialization. +- It MUST be available (e.g., proper headers must be included) everywhere you use the conversions. + +Other Important points: + +- When using `get()`, undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. If you desire an exception in this circumstance use [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT()`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/index.md) which behaves identically except for throwing an exception on unrecognized values. +- If an enum or JSON value is specified more than once in your map, the first matching occurrence from the top of the map will be returned when converting to or from JSON. +- To disable the default serialization of enumerators as integers and force a compiler error instead, see [`JSON_DISABLE_ENUM_SERIALIZATION`](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md). diff --git a/features/index.html b/features/index.html index 953d30437..ca7f64a7d 100644 --- a/features/index.html +++ b/features/index.html @@ -1 +1 @@ - Features - JSON for Modern C++

    Features

    This section describes the features of the library in detail. If you are new to the library, the pages below are roughly ordered along a typical workflow: create or parse a value, access and modify it, convert it to and from your own C++ types, and finally serialize it again.

    Creating and reading values

    Accessing and modifying values

    Converting to and from C++ types

    Serializing values

    How values are stored and configured

    Looking for a specific function?

    This section gives conceptual overviews. For the precise signature, parameters, and return value of a function, see the API Documentation.

    \ No newline at end of file + Features - JSON for Modern C++

    Features

    This section describes the features of the library in detail. If you are new to the library, the pages below are roughly ordered along a typical workflow: create or parse a value, access and modify it, convert it to and from your own C++ types, and finally serialize it again.

    Creating and reading values

    Accessing and modifying values

    Converting to and from C++ types

    Serializing values

    How values are stored and configured

    Looking for a specific function?

    This section gives conceptual overviews. For the precise signature, parameters, and return value of a function, see the API Documentation.

    \ No newline at end of file diff --git a/features/index.md b/features/index.md new file mode 100644 index 000000000..40be7244d --- /dev/null +++ b/features/index.md @@ -0,0 +1,39 @@ +# Features + +This section describes the features of the library in detail. If you are new to the library, the pages below are roughly ordered along a typical workflow: create or parse a value, access and modify it, convert it to and from your own C++ types, and finally serialize it again. + +## Creating and reading values + +- [Creating JSON values](https://json.nlohmann.me/features/creating_values/index.md) — build values from literals, initializer lists, and STL containers, and understand the `{}` vs. `[]` ambiguity. +- [Parsing](https://json.nlohmann.me/features/parsing/index.md) — read a JSON value from a string, file, or stream, including [JSON Lines](https://json.nlohmann.me/features/parsing/json_lines/index.md), [callbacks](https://json.nlohmann.me/features/parsing/parser_callbacks/index.md), the [SAX interface](https://json.nlohmann.me/features/parsing/sax_interface/index.md), and [error handling](https://json.nlohmann.me/features/parsing/parse_exceptions/index.md). +- [Comments](https://json.nlohmann.me/features/comments/index.md) and [trailing commas](https://json.nlohmann.me/features/trailing_commas/index.md) — opt-in relaxations of the JSON grammar. + +## Accessing and modifying values + +- [Element access](https://json.nlohmann.me/features/element_access/index.md) — unchecked ([`operator[]`](https://json.nlohmann.me/features/element_access/unchecked_access/index.md)), checked ([`at`](https://json.nlohmann.me/features/element_access/checked_access/index.md)), and access with a [default value](https://json.nlohmann.me/features/element_access/default_value/index.md). +- [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) — address values deep inside a document with [RFC 6901](https://tools.ietf.org/html/rfc6901) pointers. +- [Iterators](https://json.nlohmann.me/features/iterators/index.md) — traverse arrays and objects. +- [Modifying values](https://json.nlohmann.me/features/modifying_values/index.md) — add, update, merge, and remove elements. +- [JSON Patch and Diff](https://json.nlohmann.me/features/json_patch/index.md) and [JSON Merge Patch](https://json.nlohmann.me/features/merge_patch/index.md) — apply and compute structured changes. + +## Converting to and from C++ types + +- [Converting values](https://json.nlohmann.me/features/conversions/index.md) — get values out with [`get`](https://json.nlohmann.me/api/basic_json/get/index.md)/[`get_to`](https://json.nlohmann.me/api/basic_json/get_to/index.md), and understand implicit conversions. +- [Arbitrary types conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) — teach the library about your own structs and classes. +- [Specializing enum conversion](https://json.nlohmann.me/features/enum_conversion/index.md) — map enums to strings instead of integers. + +## Serializing values + +- [Serialization](https://json.nlohmann.me/features/serialization/index.md) — turn a value back into JSON text with [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md), including pretty-printing and handling of non-ASCII and invalid UTF-8. +- [Binary formats](https://json.nlohmann.me/features/binary_formats/index.md) — encode values more compactly as [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md), [BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md), [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md), [MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md), or [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md). +- [Binary values](https://json.nlohmann.me/features/binary_values/index.md) — store and exchange raw byte sequences. + +## How values are stored and configured + +- [Types](https://json.nlohmann.me/features/types/index.md) and [number handling](https://json.nlohmann.me/features/types/number_handling/index.md) — how JSON types map to C++ types and how numbers are treated. +- [Object order](https://json.nlohmann.me/features/object_order/index.md) — keep insertion order with [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md). +- [Runtime assertions](https://json.nlohmann.me/features/assertions/index.md), [supported macros](https://json.nlohmann.me/features/macros/index.md), the [`nlohmann` namespace](https://json.nlohmann.me/features/namespace/index.md), and [C++ modules](https://json.nlohmann.me/features/modules/index.md) — build-time and runtime configuration. + +Looking for a specific function? + +This section gives conceptual overviews. For the precise signature, parameters, and return value of a function, see the [API Documentation](https://json.nlohmann.me/api/basic_json/index.md). diff --git a/features/iterators.md b/features/iterators.md new file mode 100644 index 000000000..f45b92fdc --- /dev/null +++ b/features/iterators.md @@ -0,0 +1,155 @@ +# Iterators + +## Overview + +A `basic_json` value is a container and allows access via iterators. Depending on the value type, `basic_json` stores zero or more values. + +As for other containers, `begin()` returns an iterator to the first value and `end()` returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, `begin()` will return `end()`. + +![Illustration from cppreference.com](../images/range-begin-end.svg) + +### Iteration order for objects + +When iterating over objects, values are ordered with respect to the `object_comparator_t` type which defaults to `std::less`. See the [types documentation](types/index.md#key-order) for more information. + +??? example + + ```cpp + // create JSON object {"one": 1, "two": 2, "three": 3} + json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + for (auto it = j.begin(); it != j.end(); ++it) + { + std::cout << *it << std::endl; + } + ``` + + Output: + + ```json + 1 + 3 + 2 + ``` + + The reason for the order is the lexicographic ordering of the object keys "one", "three", "two". + +### Access object keys during iteration + +The JSON iterators have two member functions, `key()` and `value()` to access the object key and stored value, respectively. When calling `key()` on a non-object iterator, an [invalid_iterator.207](../home/exceptions.md#jsonexceptioninvalid_iterator207) exception is thrown. + +??? example + + ```cpp + // create JSON object {"one": 1, "two": 2, "three": 3} + json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + for (auto it = j.begin(); it != j.end(); ++it) + { + std::cout << it.key() << " : " << it.value() << std::endl; + } + ``` + + Output: + + ```json + one : 1 + three : 3 + two : 2 + ``` + +### Range-based for loops + +C++11 allows using range-based for loops to iterate over a container. + +```cpp +for (auto it : j_object) +{ + // "it" is of type json::reference and has no key() member + std::cout << "value: " << it << '\n'; +} +``` + +For this reason, the `items()` function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator. + +```cpp +for (auto& el : j_object.items()) +{ + std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; +} +``` + +The items() function also allows using structured bindings (C++17): + +```cpp +for (auto& [key, val] : j_object.items()) +{ + std::cout << "key: " << key << ", value:" << val << '\n'; +} +``` + +!!! note + + When iterating over an array, `key()` will return the index of the element as string. For primitive types (e.g., numbers), `key()` returns an empty string. + +!!! warning + + Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See [#2040](https://github.com/nlohmann/json/issues/2040) for more information. + +### Reverse iteration order + +`rbegin()` and `rend()` return iterators in the reverse sequence. + +![Illustration from cppreference.com](../images/range-rbegin-rend.svg) + +??? example + + ```cpp + json j = {1, 2, 3, 4}; + + for (auto it = j.rbegin(); it != j.rend(); ++it) + { + std::cout << *it << std::endl; + } + ``` + + Output: + + ```json + 4 + 3 + 2 + 1 + ``` + +### Iterating strings and binary values + +Note that "value" means a JSON value in this setting, not values stored in the underlying containers. That is, `*begin()` returns the complete string or binary array and is also safe if the underlying string or binary array is empty. + +??? example + + ```cpp + json j = "Hello, world"; + for (auto it = j.begin(); it != j.end(); ++it) + { + std::cout << *it << std::endl; + } + ``` + + Output: + + ```json + "Hello, world" + ``` + +## Iterator invalidation + +| Operations | invalidated iterators | +|------------|-----------------------| +| `clear` | all | diff --git a/features/iterators/index.html b/features/iterators/index.html index 6b4db0ebc..b805bdf36 100644 --- a/features/iterators/index.html +++ b/features/iterators/index.html @@ -53,4 +53,4 @@ std::cout << *it << std::endl; }

    Output:

    "Hello, world"
    -

    Iterator invalidation

    Operations invalidated iterators
    clear all
    \ No newline at end of file +

    Iterator invalidation

    Operations invalidated iterators
    clear all
    \ No newline at end of file diff --git a/features/iterators/index.md b/features/iterators/index.md new file mode 100644 index 000000000..594feebff --- /dev/null +++ b/features/iterators/index.md @@ -0,0 +1,151 @@ +# Iterators + +## Overview + +A `basic_json` value is a container and allows access via iterators. Depending on the value type, `basic_json` stores zero or more values. + +As for other containers, `begin()` returns an iterator to the first value and `end()` returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, `begin()` will return `end()`. + +### Iteration order for objects + +When iterating over objects, values are ordered with respect to the `object_comparator_t` type which defaults to `std::less`. See the [types documentation](https://json.nlohmann.me/features/types/#key-order) for more information. + +Example + +``` +// create JSON object {"one": 1, "two": 2, "three": 3} +json j; +j["one"] = 1; +j["two"] = 2; +j["three"] = 3; + +for (auto it = j.begin(); it != j.end(); ++it) +{ + std::cout << *it << std::endl; +} +``` + +Output: + +``` +1 +3 +2 +``` + +The reason for the order is the lexicographic ordering of the object keys "one", "three", "two". + +### Access object keys during iteration + +The JSON iterators have two member functions, `key()` and `value()` to access the object key and stored value, respectively. When calling `key()` on a non-object iterator, an [invalid_iterator.207](https://json.nlohmann.me/home/exceptions/#jsonexceptioninvalid_iterator207) exception is thrown. + +Example + +``` +// create JSON object {"one": 1, "two": 2, "three": 3} +json j; +j["one"] = 1; +j["two"] = 2; +j["three"] = 3; + +for (auto it = j.begin(); it != j.end(); ++it) +{ + std::cout << it.key() << " : " << it.value() << std::endl; +} +``` + +Output: + +``` +one : 1 +three : 3 +two : 2 +``` + +### Range-based for loops + +C++11 allows using range-based for loops to iterate over a container. + +``` +for (auto it : j_object) +{ + // "it" is of type json::reference and has no key() member + std::cout << "value: " << it << '\n'; +} +``` + +For this reason, the `items()` function allows accessing `iterator::key()` and `iterator::value()` during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator. + +``` +for (auto& el : j_object.items()) +{ + std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; +} +``` + +The items() function also allows using structured bindings (C++17): + +``` +for (auto& [key, val] : j_object.items()) +{ + std::cout << "key: " << key << ", value:" << val << '\n'; +} +``` + +Note + +When iterating over an array, `key()` will return the index of the element as string. For primitive types (e.g., numbers), `key()` returns an empty string. + +Warning + +Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See [#2040](https://github.com/nlohmann/json/issues/2040) for more information. + +### Reverse iteration order + +`rbegin()` and `rend()` return iterators in the reverse sequence. + +Example + +``` +json j = {1, 2, 3, 4}; + +for (auto it = j.rbegin(); it != j.rend(); ++it) +{ + std::cout << *it << std::endl; +} +``` + +Output: + +``` +4 +3 +2 +1 +``` + +### Iterating strings and binary values + +Note that "value" means a JSON value in this setting, not values stored in the underlying containers. That is, `*begin()` returns the complete string or binary array and is also safe if the underlying string or binary array is empty. + +Example + +``` +json j = "Hello, world"; +for (auto it = j.begin(); it != j.end(); ++it) +{ + std::cout << *it << std::endl; +} +``` + +Output: + +``` +"Hello, world" +``` + +## Iterator invalidation + +| Operations | invalidated iterators | +| ---------- | --------------------- | +| `clear` | all | diff --git a/features/json_patch.md b/features/json_patch.md new file mode 100644 index 000000000..835f07f90 --- /dev/null +++ b/features/json_patch.md @@ -0,0 +1,47 @@ +# JSON Patch and Diff + +## Patches + +JSON Patch ([RFC 6902](https://tools.ietf.org/html/rfc6902)) defines a JSON document structure for expressing a sequence +of operations to apply to a JSON document. With the `patch` function, a JSON Patch is applied to the current JSON value +by executing all operations from the patch. + +??? example + + The following code shows how a JSON patch is applied to a value. + + ```cpp + --8<-- "examples/patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/patch.output" + ``` + +## Diff + +The library can also calculate a JSON patch (i.e., a **diff**) given two JSON values. + +!!! success "Invariant" + + For two JSON values *source* and *target*, the following code yields always true: + + ```cpp + source.patch(diff(source, target)) == target; + ``` + +??? example + + The following code shows how a JSON patch is created as a diff for two JSON values. + + ```cpp + --8<-- "examples/diff.cpp" + ``` + + Output: + + ```json + --8<-- "examples/diff.output" + ``` diff --git a/features/json_patch/index.html b/features/json_patch/index.html index a391fea5b..fcc6eab40 100644 --- a/features/json_patch/index.html +++ b/features/json_patch/index.html @@ -105,4 +105,4 @@ "world" ] } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/json_patch/index.md b/features/json_patch/index.md new file mode 100644 index 000000000..a19aaa5f7 --- /dev/null +++ b/features/json_patch/index.md @@ -0,0 +1,147 @@ +# JSON Patch and Diff + +## Patches + +JSON Patch ([RFC 6902](https://tools.ietf.org/html/rfc6902)) defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With the `patch` function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. + +Example + +The following code shows how a JSON patch is applied to a value. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json doc = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the patch + json patch = R"( + [ + { "op": "replace", "path": "/baz", "value": "boo" }, + { "op": "add", "path": "/hello", "value": ["world"] }, + { "op": "remove", "path": "/foo"} + ] + )"_json; + + // apply the patch + json patched_doc = doc.patch(patch); + + // output original and patched document + std::cout << std::setw(4) << doc << "\n\n" + << std::setw(4) << patched_doc << std::endl; +} +``` + +Output: + +``` +{ + "baz": "qux", + "foo": "bar" +} + +{ + "baz": "boo", + "hello": [ + "world" + ] +} +``` + +## Diff + +The library can also calculate a JSON patch (i.e., a **diff**) given two JSON values. + +Invariant + +For two JSON values *source* and *target*, the following code yields always true: + +``` +source.patch(diff(source, target)) == target; +``` + +Example + +The following code shows how a JSON patch is created as a diff for two JSON values. + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the source document + json source = R"( + { + "baz": "qux", + "foo": "bar" + } + )"_json; + + // the target document + json target = R"( + { + "baz": "boo", + "hello": [ + "world" + ] + } + )"_json; + + // create the patch + json patch = json::diff(source, target); + + // roundtrip + json patched_source = source.patch(patch); + + // output patch and roundtrip result + std::cout << std::setw(4) << patch << "\n\n" + << std::setw(4) << patched_source << std::endl; +} +``` + +Output: + +``` +[ + { + "op": "replace", + "path": "/baz", + "value": "boo" + }, + { + "op": "remove", + "path": "/foo" + }, + { + "op": "add", + "path": "/hello", + "value": [ + "world" + ] + } +] + +{ + "baz": "boo", + "hello": [ + "world" + ] +} +``` diff --git a/features/json_pointer.md b/features/json_pointer.md new file mode 100644 index 000000000..a16e8df24 --- /dev/null +++ b/features/json_pointer.md @@ -0,0 +1,126 @@ +# JSON Pointer + +## Introduction + +The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as an alternative means to +address structured values. A JSON Pointer is a string that identifies a specific value within a JSON document. + +Consider the following JSON document + +```json +{ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +} +``` + +Then every value inside the JSON document can be identified as follows: + +| JSON Pointer | JSON value | +|-------------------|----------------------------------------------------------------------------------| +| `` | `#!json {"array":["A","B","C"],"nested":{"one":1,"two":2,"three":[true,false]}}` | +| `/array` | `#!json ["A","B","C"]` | +| `/array/0` | `#!json A` | +| `/array/1` | `#!json B` | +| `/array/2` | `#!json C` | +| `/nested` | `#!json {"one":1,"two":2,"three":[true,false]}` | +| `/nested/one` | `#!json 1` | +| `/nested/two` | `#!json 2` | +| `/nested/three` | `#!json [true,false]` | +| `/nested/three/0` | `#!json true` | +| `/nested/three/1` | `#!json false` | + +Note `/` does not identify the root (i.e., the whole document), but an object entry with empty key `""`. See +[RFC 6901](https://tools.ietf.org/html/rfc6901) for more information. + +## JSON Pointer creation + +JSON Pointers can be created from a string: + +```cpp +json::json_pointer p("/nested/one"); +``` + +Furthermore, a user-defined string literal can be used to achieve the same result: + +```cpp +auto p = "/nested/one"_json_pointer; +``` + +The escaping rules of [RFC 6901](https://tools.ietf.org/html/rfc6901) are implemented. See the +[constructor documentation](../api/json_pointer/json_pointer.md) for more information. + +## Value access + +JSON Pointers can be used in the [`at`](../api/basic_json/at.md), [`operator[]`](../api/basic_json/operator%5B%5D.md), +and [`value`](../api/basic_json/value.md) functions just like object keys or array indices. + +```cpp +// the JSON value from above +auto j = json::parse(R"({ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +})"); + +// access values +auto val = j[""_json_pointer]; // {"array":["A","B","C"],...} +auto val1 = j["/nested/one"_json_pointer]; // 1 +auto val2 = j.at(json::json_pointer("/nested/three/1")); // false +auto val3 = j.value(json::json_pointer("/nested/four"), 0); // 0 +``` + +## Flatten / unflatten + +The library implements a function [`flatten`](../api/basic_json/flatten.md) to convert any JSON document into a JSON +object where each key is a JSON Pointer and each value is a primitive JSON value (i.e., a string, boolean, number, or +null). + +```cpp +// the JSON value from above +auto j = json::parse(R"({ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +})"); + +// create flattened value +auto j_flat = j.flatten(); +``` + +The resulting value `j_flat` is: + +```json +{ + "/array/0": "A", + "/array/1": "B", + "/array/2": "C", + "/nested/one": 1, + "/nested/two": 2, + "/nested/three/0": true, + "/nested/three/1": false +} +``` + +The reverse function, [`unflatten`](../api/basic_json/unflatten.md) recreates the original value. + +```cpp +auto j_original = j_flat.unflatten(); +``` + +## See also + +- Class [`json_pointer`](../api/json_pointer/index.md) +- Function [`flatten`](../api/basic_json/flatten.md) +- Function [`unflatten`](../api/basic_json/unflatten.md) +- [JSON Patch](json_patch.md) diff --git a/features/json_pointer/index.html b/features/json_pointer/index.html index ab44f1665..5a12b330d 100644 --- a/features/json_pointer/index.html +++ b/features/json_pointer/index.html @@ -45,4 +45,4 @@ "/nested/three/1": false }

    The reverse function, unflatten recreates the original value.

    auto j_original = j_flat.unflatten();
    -

    See also

    \ No newline at end of file +

    See also

    \ No newline at end of file diff --git a/features/json_pointer/index.md b/features/json_pointer/index.md new file mode 100644 index 000000000..7c7c989c4 --- /dev/null +++ b/features/json_pointer/index.md @@ -0,0 +1,120 @@ +# JSON Pointer + +## Introduction + +The library supports **JSON Pointer** ([RFC 6901](https://tools.ietf.org/html/rfc6901)) as an alternative means to address structured values. A JSON Pointer is a string that identifies a specific value within a JSON document. + +Consider the following JSON document + +``` +{ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +} +``` + +Then every value inside the JSON document can be identified as follows: + +| JSON Pointer | JSON value | +| ----------------- | ------------------------------------------------------------------------- | +| \`\` | `{"array":["A","B","C"],"nested":{"one":1,"two":2,"three":[true,false]}}` | +| `/array` | `["A","B","C"]` | +| `/array/0` | `A` | +| `/array/1` | `B` | +| `/array/2` | `C` | +| `/nested` | `{"one":1,"two":2,"three":[true,false]}` | +| `/nested/one` | `1` | +| `/nested/two` | `2` | +| `/nested/three` | `[true,false]` | +| `/nested/three/0` | `true` | +| `/nested/three/1` | `false` | + +Note `/` does not identify the root (i.e., the whole document), but an object entry with empty key `""`. See [RFC 6901](https://tools.ietf.org/html/rfc6901) for more information. + +## JSON Pointer creation + +JSON Pointers can be created from a string: + +``` +json::json_pointer p("/nested/one"); +``` + +Furthermore, a user-defined string literal can be used to achieve the same result: + +``` +auto p = "/nested/one"_json_pointer; +``` + +The escaping rules of [RFC 6901](https://tools.ietf.org/html/rfc6901) are implemented. See the [constructor documentation](https://json.nlohmann.me/api/json_pointer/json_pointer/index.md) for more information. + +## Value access + +JSON Pointers can be used in the [`at`](https://json.nlohmann.me/api/basic_json/at/index.md), [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md), and [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) functions just like object keys or array indices. + +``` +// the JSON value from above +auto j = json::parse(R"({ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +})"); + +// access values +auto val = j[""_json_pointer]; // {"array":["A","B","C"],...} +auto val1 = j["/nested/one"_json_pointer]; // 1 +auto val2 = j.at(json::json_pointer("/nested/three/1")); // false +auto val3 = j.value(json::json_pointer("/nested/four"), 0); // 0 +``` + +## Flatten / unflatten + +The library implements a function [`flatten`](https://json.nlohmann.me/api/basic_json/flatten/index.md) to convert any JSON document into a JSON object where each key is a JSON Pointer and each value is a primitive JSON value (i.e., a string, boolean, number, or null). + +``` +// the JSON value from above +auto j = json::parse(R"({ + "array": ["A", "B", "C"], + "nested": { + "one": 1, + "two": 2, + "three": [true, false] + } +})"); + +// create flattened value +auto j_flat = j.flatten(); +``` + +The resulting value `j_flat` is: + +``` +{ + "/array/0": "A", + "/array/1": "B", + "/array/2": "C", + "/nested/one": 1, + "/nested/two": 2, + "/nested/three/0": true, + "/nested/three/1": false +} +``` + +The reverse function, [`unflatten`](https://json.nlohmann.me/api/basic_json/unflatten/index.md) recreates the original value. + +``` +auto j_original = j_flat.unflatten(); +``` + +## See also + +- Class [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) +- Function [`flatten`](https://json.nlohmann.me/api/basic_json/flatten/index.md) +- Function [`unflatten`](https://json.nlohmann.me/api/basic_json/unflatten/index.md) +- [JSON Patch](https://json.nlohmann.me/features/json_patch/index.md) diff --git a/features/macros.md b/features/macros.md new file mode 100644 index 000000000..1d169fdeb --- /dev/null +++ b/features/macros.md @@ -0,0 +1,174 @@ +# Supported Macros + +Some aspects of the library can be configured by defining preprocessor macros before including the `json.hpp` header. +See also the [API documentation for macros](../api/macros/index.md) for examples and more information. + +## `JSON_ASSERT(x)` + +This macro controls which code is executed for [runtime assertions](assertions.md) of the library. + +See [full documentation of `JSON_ASSERT(x)`](../api/macros/json_assert.md). + +## `JSON_BRACE_INIT_COPY_SEMANTICS` + +When defined to `1`, single-element brace initialization of a `basic_json` value (e.g., `#!cpp json j{value};`) is +treated as a copy/move of the element rather than wrapping it in a single-element array. The default value is `0`, which +preserves the existing behavior. + +See [full documentation of `JSON_BRACE_INIT_COPY_SEMANTICS`](../api/macros/json_brace_init_copy_semantics.md). + +## `JSON_CATCH_USER(exception)` + +This macro overrides [`#!cpp catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library. + +See [full documentation of `JSON_CATCH_USER(exception)`](../api/macros/json_throw_user.md). + +## `JSON_DIAGNOSTICS` + +This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable +(default). + +When enabled, exception messages contain a [JSON Pointer](json_pointer.md) to the JSON value that triggered the +exception, see [Extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) for an example. Note +that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead. + +The diagnostics messages can also be controlled with the CMake option +[`JSON_Diagnostics`](../integration/cmake.md#json_diagnostics) (`OFF` by default) which sets `JSON_DIAGNOSTICS` +accordingly. + +See [full documentation of `JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). + +## `JSON_DIAGNOSTIC_POSITIONS` + +When enabled, two new member functions [`start_pos()`](../api/basic_json/start_pos.md) and +[`end_pos()`](../api/basic_json/end_pos.md) are added to [`basic_json`](../api/basic_json/index.md) values. If the value +was created by calling the[`parse`](../api/basic_json/parse.md) function, then these functions allow querying the byte +positions of the value in the input it was parsed from. The byte positions are also used in exceptions to help locate +errors. + +The diagnostics positions can also be controlled with the CMake option +[`JSON_Diagnostic_Positions`](../integration/cmake.md#json_diagnostic_positions) (`OFF` by default) which sets +`JSON_DIAGNOSTIC_POSITIONS` accordingly. + +See [full documentation of `JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md) + +## `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`, `JSON_HAS_CPP_23`, `JSON_HAS_CPP_26` + +The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` +support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ +standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is +unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be +detected incorrectly. + +See [full documentation of `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`, `JSON_HAS_CPP_23`, and `JSON_HAS_CPP_26`](../api/macros/json_has_cpp_11.md). + +## `JSON_HAS_FILESYSTEM`, `JSON_HAS_EXPERIMENTAL_FILESYSTEM` + +When compiling with C++17, the library provides conversions from and to `std::filesystem::path`. As compiler support +for filesystem is limited, the library tries to detect whether ``/`std::filesystem` (`JSON_HAS_FILESYSTEM`) +or ``/`std::experimental::filesystem` (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used. +To override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`. + +See [full documentation of `JSON_HAS_FILESYSTEM` and `JSON_HAS_EXPERIMENTAL_FILESYSTEM`](../api/macros/json_has_filesystem.md). + +## `JSON_NOEXCEPTION` + +Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. + +See [full documentation of `JSON_NOEXCEPTION`](../api/macros/json_noexception.md). + +## `JSON_DISABLE_ENUM_SERIALIZATION` + +When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md). + +See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md). + +## `JSON_NO_IO` + +When defined, headers ``, ``, ``, ``, and `` are not included and parse functions +relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for +security reasons (e.g., Intel Software Guard Extensions (SGX)). + +See [full documentation of `JSON_NO_IO`](../api/macros/json_no_io.md). + +## `JSON_SKIP_LIBRARY_VERSION_CHECK` + +When defined, the library will not create a compiler warning when a different version of the library was already +included. + +See [full documentation of `JSON_SKIP_LIBRARY_VERSION_CHECK`](../api/macros/json_skip_library_version_check.md). + +## `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK` + +When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows +using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used. + +See [full documentation of `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`](../api/macros/json_skip_unsupported_compiler_check.md). + +## `JSON_THROW_USER(exception)` + +This macro overrides `#!cpp throw` calls inside the library. The argument is the exception to be thrown. + +See [full documentation of `JSON_THROW_USER(exception)`](../api/macros/json_throw_user.md). + +## `JSON_TRY_USER` + +This macro overrides `#!cpp try` calls inside the library. + +See [full documentation of `JSON_TRY_USER`](../api/macros/json_throw_user.md). + +## `JSON_USE_IMPLICIT_CONVERSIONS` + +When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. + +See [full documentation of `JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md). + +## `JSON_USE_GLOBAL_UDLS` + +When defined to `1` (default), the user-defined string literals `operator""_json` and `operator""_json_pointer` are +placed into the global namespace instead of `nlohmann::literals::json_literals`. + +See [full documentation of `JSON_USE_GLOBAL_UDLS`](../api/macros/json_use_global_udls.md). + +## `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON` + +When defined to `1`, the library restores the legacy behavior in which a discarded value compared equal to itself. This +behavior is deprecated and switched off (`0`) by default. + +See [full documentation of `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md). + +## `NLOHMANN_DEFINE_TYPE_*(...)`, `NLOHMANN_DEFINE_DERIVED_TYPE_*(...)` + +The library defines 12 macros to simplify the serialization/deserialization of types. See the page on +[arbitrary type conversion](arbitrary_types.md#simplify-your-life-with-macros) for a detailed discussion. + +## `NLOHMANN_JSON_NAMESPACE`, `NLOHMANN_JSON_NAMESPACE_BEGIN`, `NLOHMANN_JSON_NAMESPACE_END`, `NLOHMANN_JSON_NAMESPACE_NO_VERSION` + +These macros relate to the versioned, inline `nlohmann` namespace: + +- `NLOHMANN_JSON_NAMESPACE` evaluates to the full name of the `nlohmann` namespace (including the inline ABI namespace). +- `NLOHMANN_JSON_NAMESPACE_BEGIN` / `NLOHMANN_JSON_NAMESPACE_END` open and close the namespace (for example, to add + specializations). +- `NLOHMANN_JSON_NAMESPACE_NO_VERSION`, when defined to `1`, omits the version component from the inline namespace. + +See the [`nlohmann` Namespace](namespace.md) page, and the full documentation of +[`NLOHMANN_JSON_NAMESPACE`](../api/macros/nlohmann_json_namespace.md), +[`NLOHMANN_JSON_NAMESPACE_BEGIN` / `NLOHMANN_JSON_NAMESPACE_END`](../api/macros/nlohmann_json_namespace_begin.md), and +[`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](../api/macros/nlohmann_json_namespace_no_version.md). + +## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)` + +This macro simplifies the serialization/deserialization of enum types. See +[Specializing enum conversion](enum_conversion.md) for more information. + +See [full documentation of `NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md). + +A strict variant [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](../api/macros/nlohmann_json_serialize_enum_strict.md) throws an +exception on undefined input instead of falling back to the first mapping. + +## `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, `NLOHMANN_JSON_VERSION_PATCH` + +These macros are defined by the library and contain the version numbers according to +[Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). + +See [full documentation of `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and `NLOHMANN_JSON_VERSION_PATCH`](../api/macros/nlohmann_json_version_major.md). diff --git a/features/macros/index.html b/features/macros/index.html index f52ee8591..5b4da48bb 100644 --- a/features/macros/index.html +++ b/features/macros/index.html @@ -1 +1 @@ - Supported Macros - JSON for Modern C++

    Supported Macros

    Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the API documentation for macros for examples and more information.

    JSON_ASSERT(x)

    This macro controls which code is executed for runtime assertions of the library.

    See full documentation of JSON_ASSERT(x).

    JSON_BRACE_INIT_COPY_SEMANTICS

    When defined to 1, single-element brace initialization of a basic_json value (e.g., json j{value};) is treated as a copy/move of the element rather than wrapping it in a single-element array. The default value is 0, which preserves the existing behavior.

    See full documentation of JSON_BRACE_INIT_COPY_SEMANTICS.

    JSON_CATCH_USER(exception)

    This macro overrides catch calls inside the library.

    See full documentation of JSON_CATCH_USER(exception).

    JSON_DIAGNOSTICS

    This macro enables extended diagnostics for exception messages. Possible values are 1 to enable or 0 to disable (default).

    When enabled, exception messages contain a JSON Pointer to the JSON value that triggered the exception, see Extended diagnostic messages for an example. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.

    The diagnostics messages can also be controlled with the CMake option JSON_Diagnostics (OFF by default) which sets JSON_DIAGNOSTICS accordingly.

    See full documentation of JSON_DIAGNOSTICS.

    JSON_DIAGNOSTIC_POSITIONS

    When enabled, two new member functions start_pos() and end_pos() are added to basic_json values. If the value was created by calling theparse function, then these functions allow querying the byte positions of the value in the input it was parsed from. The byte positions are also used in exceptions to help locate errors.

    The diagnostics positions can also be controlled with the CMake option JSON_Diagnostic_Positions (OFF by default) which sets JSON_DIAGNOSTIC_POSITIONS accordingly.

    See full documentation of JSON_DIAGNOSTIC_POSITIONS

    JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26

    The library targets C++11, but also supports some features introduced in later C++ versions (e.g., std::string_view support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.

    See full documentation of JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, and JSON_HAS_CPP_26.

    JSON_HAS_FILESYSTEM, JSON_HAS_EXPERIMENTAL_FILESYSTEM

    When compiling with C++17, the library provides conversions from and to std::filesystem::path. As compiler support for filesystem is limited, the library tries to detect whether <filesystem>/std::filesystem (JSON_HAS_FILESYSTEM) or <experimental/filesystem>/std::experimental::filesystem (JSON_HAS_EXPERIMENTAL_FILESYSTEM) should be used. To override the built-in check, define JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM to 1.

    See full documentation of JSON_HAS_FILESYSTEM and JSON_HAS_EXPERIMENTAL_FILESYSTEM.

    JSON_NOEXCEPTION

    Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION.

    See full documentation of JSON_NOEXCEPTION.

    JSON_DISABLE_ENUM_SERIALIZATION

    When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using NLOHMANN_JSON_SERIALIZE_ENUM.

    See full documentation of JSON_DISABLE_ENUM_SERIALIZATION.

    JSON_NO_IO

    When defined, headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> are not included and parse functions relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)).

    See full documentation of JSON_NO_IO.

    JSON_SKIP_LIBRARY_VERSION_CHECK

    When defined, the library will not create a compiler warning when a different version of the library was already included.

    See full documentation of JSON_SKIP_LIBRARY_VERSION_CHECK.

    JSON_SKIP_UNSUPPORTED_COMPILER_CHECK

    When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.

    See full documentation of JSON_SKIP_UNSUPPORTED_COMPILER_CHECK.

    JSON_THROW_USER(exception)

    This macro overrides throw calls inside the library. The argument is the exception to be thrown.

    See full documentation of JSON_THROW_USER(exception).

    JSON_TRY_USER

    This macro overrides try calls inside the library.

    See full documentation of JSON_TRY_USER.

    JSON_USE_IMPLICIT_CONVERSIONS

    When defined to 0, implicit conversions are switched off. By default, implicit conversions are switched on.

    See full documentation of JSON_USE_IMPLICIT_CONVERSIONS.

    JSON_USE_GLOBAL_UDLS

    When defined to 1 (default), the user-defined string literals operator""_json and operator""_json_pointer are placed into the global namespace instead of nlohmann::literals::json_literals.

    See full documentation of JSON_USE_GLOBAL_UDLS.

    JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON

    When defined to 1, the library restores the legacy behavior in which a discarded value compared equal to itself. This behavior is deprecated and switched off (0) by default.

    See full documentation of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.

    NLOHMANN_DEFINE_TYPE_*(...), NLOHMANN_DEFINE_DERIVED_TYPE_*(...)

    The library defines 12 macros to simplify the serialization/deserialization of types. See the page on arbitrary type conversion for a detailed discussion.

    NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END, NLOHMANN_JSON_NAMESPACE_NO_VERSION

    These macros relate to the versioned, inline nlohmann namespace:

    • NLOHMANN_JSON_NAMESPACE evaluates to the full name of the nlohmann namespace (including the inline ABI namespace).
    • NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END open and close the namespace (for example, to add specializations).
    • NLOHMANN_JSON_NAMESPACE_NO_VERSION, when defined to 1, omits the version component from the inline namespace.

    See the nlohmann Namespace page, and the full documentation of NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END, and NLOHMANN_JSON_NAMESPACE_NO_VERSION.

    NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)

    This macro simplifies the serialization/deserialization of enum types. See Specializing enum conversion for more information.

    See full documentation of NLOHMANN_JSON_SERIALIZE_ENUM.

    A strict variant NLOHMANN_JSON_SERIALIZE_ENUM_STRICT throws an exception on undefined input instead of falling back to the first mapping.

    NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH

    These macros are defined by the library and contain the version numbers according to Semantic Versioning 2.0.0.

    See full documentation of NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, and NLOHMANN_JSON_VERSION_PATCH.

    \ No newline at end of file + Supported Macros - JSON for Modern C++

    Supported Macros

    Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the API documentation for macros for examples and more information.

    JSON_ASSERT(x)

    This macro controls which code is executed for runtime assertions of the library.

    See full documentation of JSON_ASSERT(x).

    JSON_BRACE_INIT_COPY_SEMANTICS

    When defined to 1, single-element brace initialization of a basic_json value (e.g., json j{value};) is treated as a copy/move of the element rather than wrapping it in a single-element array. The default value is 0, which preserves the existing behavior.

    See full documentation of JSON_BRACE_INIT_COPY_SEMANTICS.

    JSON_CATCH_USER(exception)

    This macro overrides catch calls inside the library.

    See full documentation of JSON_CATCH_USER(exception).

    JSON_DIAGNOSTICS

    This macro enables extended diagnostics for exception messages. Possible values are 1 to enable or 0 to disable (default).

    When enabled, exception messages contain a JSON Pointer to the JSON value that triggered the exception, see Extended diagnostic messages for an example. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.

    The diagnostics messages can also be controlled with the CMake option JSON_Diagnostics (OFF by default) which sets JSON_DIAGNOSTICS accordingly.

    See full documentation of JSON_DIAGNOSTICS.

    JSON_DIAGNOSTIC_POSITIONS

    When enabled, two new member functions start_pos() and end_pos() are added to basic_json values. If the value was created by calling theparse function, then these functions allow querying the byte positions of the value in the input it was parsed from. The byte positions are also used in exceptions to help locate errors.

    The diagnostics positions can also be controlled with the CMake option JSON_Diagnostic_Positions (OFF by default) which sets JSON_DIAGNOSTIC_POSITIONS accordingly.

    See full documentation of JSON_DIAGNOSTIC_POSITIONS

    JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, JSON_HAS_CPP_26

    The library targets C++11, but also supports some features introduced in later C++ versions (e.g., std::string_view support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly.

    See full documentation of JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20, JSON_HAS_CPP_23, and JSON_HAS_CPP_26.

    JSON_HAS_FILESYSTEM, JSON_HAS_EXPERIMENTAL_FILESYSTEM

    When compiling with C++17, the library provides conversions from and to std::filesystem::path. As compiler support for filesystem is limited, the library tries to detect whether <filesystem>/std::filesystem (JSON_HAS_FILESYSTEM) or <experimental/filesystem>/std::experimental::filesystem (JSON_HAS_EXPERIMENTAL_FILESYSTEM) should be used. To override the built-in check, define JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM to 1.

    See full documentation of JSON_HAS_FILESYSTEM and JSON_HAS_EXPERIMENTAL_FILESYSTEM.

    JSON_NOEXCEPTION

    Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION.

    See full documentation of JSON_NOEXCEPTION.

    JSON_DISABLE_ENUM_SERIALIZATION

    When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using NLOHMANN_JSON_SERIALIZE_ENUM.

    See full documentation of JSON_DISABLE_ENUM_SERIALIZATION.

    JSON_NO_IO

    When defined, headers <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream> are not included and parse functions relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)).

    See full documentation of JSON_NO_IO.

    JSON_SKIP_LIBRARY_VERSION_CHECK

    When defined, the library will not create a compiler warning when a different version of the library was already included.

    See full documentation of JSON_SKIP_LIBRARY_VERSION_CHECK.

    JSON_SKIP_UNSUPPORTED_COMPILER_CHECK

    When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.

    See full documentation of JSON_SKIP_UNSUPPORTED_COMPILER_CHECK.

    JSON_THROW_USER(exception)

    This macro overrides throw calls inside the library. The argument is the exception to be thrown.

    See full documentation of JSON_THROW_USER(exception).

    JSON_TRY_USER

    This macro overrides try calls inside the library.

    See full documentation of JSON_TRY_USER.

    JSON_USE_IMPLICIT_CONVERSIONS

    When defined to 0, implicit conversions are switched off. By default, implicit conversions are switched on.

    See full documentation of JSON_USE_IMPLICIT_CONVERSIONS.

    JSON_USE_GLOBAL_UDLS

    When defined to 1 (default), the user-defined string literals operator""_json and operator""_json_pointer are placed into the global namespace instead of nlohmann::literals::json_literals.

    See full documentation of JSON_USE_GLOBAL_UDLS.

    JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON

    When defined to 1, the library restores the legacy behavior in which a discarded value compared equal to itself. This behavior is deprecated and switched off (0) by default.

    See full documentation of JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON.

    NLOHMANN_DEFINE_TYPE_*(...), NLOHMANN_DEFINE_DERIVED_TYPE_*(...)

    The library defines 12 macros to simplify the serialization/deserialization of types. See the page on arbitrary type conversion for a detailed discussion.

    NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END, NLOHMANN_JSON_NAMESPACE_NO_VERSION

    These macros relate to the versioned, inline nlohmann namespace:

    • NLOHMANN_JSON_NAMESPACE evaluates to the full name of the nlohmann namespace (including the inline ABI namespace).
    • NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END open and close the namespace (for example, to add specializations).
    • NLOHMANN_JSON_NAMESPACE_NO_VERSION, when defined to 1, omits the version component from the inline namespace.

    See the nlohmann Namespace page, and the full documentation of NLOHMANN_JSON_NAMESPACE, NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END, and NLOHMANN_JSON_NAMESPACE_NO_VERSION.

    NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)

    This macro simplifies the serialization/deserialization of enum types. See Specializing enum conversion for more information.

    See full documentation of NLOHMANN_JSON_SERIALIZE_ENUM.

    A strict variant NLOHMANN_JSON_SERIALIZE_ENUM_STRICT throws an exception on undefined input instead of falling back to the first mapping.

    NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH

    These macros are defined by the library and contain the version numbers according to Semantic Versioning 2.0.0.

    See full documentation of NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, and NLOHMANN_JSON_VERSION_PATCH.

    \ No newline at end of file diff --git a/features/macros/index.md b/features/macros/index.md new file mode 100644 index 000000000..efcb80ce5 --- /dev/null +++ b/features/macros/index.md @@ -0,0 +1,139 @@ +# Supported Macros + +Some aspects of the library can be configured by defining preprocessor macros before including the `json.hpp` header. See also the [API documentation for macros](https://json.nlohmann.me/api/macros/index.md) for examples and more information. + +## `JSON_ASSERT(x)` + +This macro controls which code is executed for [runtime assertions](https://json.nlohmann.me/features/assertions/index.md) of the library. + +See [full documentation of `JSON_ASSERT(x)`](https://json.nlohmann.me/api/macros/json_assert/index.md). + +## `JSON_BRACE_INIT_COPY_SEMANTICS` + +When defined to `1`, single-element brace initialization of a `basic_json` value (e.g., `json j{value};`) is treated as a copy/move of the element rather than wrapping it in a single-element array. The default value is `0`, which preserves the existing behavior. + +See [full documentation of `JSON_BRACE_INIT_COPY_SEMANTICS`](https://json.nlohmann.me/api/macros/json_brace_init_copy_semantics/index.md). + +## `JSON_CATCH_USER(exception)` + +This macro overrides [`catch`](https://en.cppreference.com/w/cpp/language/try_catch) calls inside the library. + +See [full documentation of `JSON_CATCH_USER(exception)`](https://json.nlohmann.me/api/macros/json_throw_user/index.md). + +## `JSON_DIAGNOSTICS` + +This macro enables extended diagnostics for exception messages. Possible values are `1` to enable or `0` to disable (default). + +When enabled, exception messages contain a [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) to the JSON value that triggered the exception, see [Extended diagnostic messages](https://json.nlohmann.me/home/exceptions/#extended-diagnostic-messages) for an example. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead. + +The diagnostics messages can also be controlled with the CMake option [`JSON_Diagnostics`](https://json.nlohmann.me/integration/cmake/#json_diagnostics) (`OFF` by default) which sets `JSON_DIAGNOSTICS` accordingly. + +See [full documentation of `JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md). + +## `JSON_DIAGNOSTIC_POSITIONS` + +When enabled, two new member functions [`start_pos()`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) and [`end_pos()`](https://json.nlohmann.me/api/basic_json/end_pos/index.md) are added to [`basic_json`](https://json.nlohmann.me/api/basic_json/index.md) values. If the value was created by calling the[`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function, then these functions allow querying the byte positions of the value in the input it was parsed from. The byte positions are also used in exceptions to help locate errors. + +The diagnostics positions can also be controlled with the CMake option [`JSON_Diagnostic_Positions`](https://json.nlohmann.me/integration/cmake/#json_diagnostic_positions) (`OFF` by default) which sets `JSON_DIAGNOSTIC_POSITIONS` accordingly. + +See [full documentation of `JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) + +## `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`, `JSON_HAS_CPP_23`, `JSON_HAS_CPP_26` + +The library targets C++11, but also supports some features introduced in later C++ versions (e.g., `std::string_view` support for C++17). For these new features, the library implements some preprocessor checks to determine the C++ standard. By defining any of these symbols, the internal check is overridden and the provided C++ version is unconditionally assumed. This can be helpful for compilers that only implement parts of the standard and would be detected incorrectly. + +See [full documentation of `JSON_HAS_CPP_11`, `JSON_HAS_CPP_14`, `JSON_HAS_CPP_17`, `JSON_HAS_CPP_20`, `JSON_HAS_CPP_23`, and `JSON_HAS_CPP_26`](https://json.nlohmann.me/api/macros/json_has_cpp_11/index.md). + +## `JSON_HAS_FILESYSTEM`, `JSON_HAS_EXPERIMENTAL_FILESYSTEM` + +When compiling with C++17, the library provides conversions from and to `std::filesystem::path`. As compiler support for filesystem is limited, the library tries to detect whether ``/`std::filesystem` (`JSON_HAS_FILESYSTEM`) or ``/`std::experimental::filesystem` (`JSON_HAS_EXPERIMENTAL_FILESYSTEM`) should be used. To override the built-in check, define `JSON_HAS_FILESYSTEM` or `JSON_HAS_EXPERIMENTAL_FILESYSTEM` to `1`. + +See [full documentation of `JSON_HAS_FILESYSTEM` and `JSON_HAS_EXPERIMENTAL_FILESYSTEM`](https://json.nlohmann.me/api/macros/json_has_filesystem/index.md). + +## `JSON_NOEXCEPTION` + +Exceptions can be switched off by defining the symbol `JSON_NOEXCEPTION`. + +See [full documentation of `JSON_NOEXCEPTION`](https://json.nlohmann.me/api/macros/json_noexception/index.md). + +## `JSON_DISABLE_ENUM_SERIALIZATION` + +When defined, default parse and serialize functions for enums are excluded and have to be provided by the user, for example, using [`NLOHMANN_JSON_SERIALIZE_ENUM`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md). + +See [full documentation of `JSON_DISABLE_ENUM_SERIALIZATION`](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md). + +## `JSON_NO_IO` + +When defined, headers ``, ``, ``, ``, and `` are not included and parse functions relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)). + +See [full documentation of `JSON_NO_IO`](https://json.nlohmann.me/api/macros/json_no_io/index.md). + +## `JSON_SKIP_LIBRARY_VERSION_CHECK` + +When defined, the library will not create a compiler warning when a different version of the library was already included. + +See [full documentation of `JSON_SKIP_LIBRARY_VERSION_CHECK`](https://json.nlohmann.me/api/macros/json_skip_library_version_check/index.md). + +## `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK` + +When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows using the library with compilers that do not fully support C++11 and may only work if unsupported features are not used. + +See [full documentation of `JSON_SKIP_UNSUPPORTED_COMPILER_CHECK`](https://json.nlohmann.me/api/macros/json_skip_unsupported_compiler_check/index.md). + +## `JSON_THROW_USER(exception)` + +This macro overrides `throw` calls inside the library. The argument is the exception to be thrown. + +See [full documentation of `JSON_THROW_USER(exception)`](https://json.nlohmann.me/api/macros/json_throw_user/index.md). + +## `JSON_TRY_USER` + +This macro overrides `try` calls inside the library. + +See [full documentation of `JSON_TRY_USER`](https://json.nlohmann.me/api/macros/json_throw_user/index.md). + +## `JSON_USE_IMPLICIT_CONVERSIONS` + +When defined to `0`, implicit conversions are switched off. By default, implicit conversions are switched on. + +See [full documentation of `JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md). + +## `JSON_USE_GLOBAL_UDLS` + +When defined to `1` (default), the user-defined string literals `operator""_json` and `operator""_json_pointer` are placed into the global namespace instead of `nlohmann::literals::json_literals`. + +See [full documentation of `JSON_USE_GLOBAL_UDLS`](https://json.nlohmann.me/api/macros/json_use_global_udls/index.md). + +## `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON` + +When defined to `1`, the library restores the legacy behavior in which a discarded value compared equal to itself. This behavior is deprecated and switched off (`0`) by default. + +See [full documentation of `JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/index.md). + +## `NLOHMANN_DEFINE_TYPE_*(...)`, `NLOHMANN_DEFINE_DERIVED_TYPE_*(...)` + +The library defines 12 macros to simplify the serialization/deserialization of types. See the page on [arbitrary type conversion](https://json.nlohmann.me/features/arbitrary_types/#simplify-your-life-with-macros) for a detailed discussion. + +## `NLOHMANN_JSON_NAMESPACE`, `NLOHMANN_JSON_NAMESPACE_BEGIN`, `NLOHMANN_JSON_NAMESPACE_END`, `NLOHMANN_JSON_NAMESPACE_NO_VERSION` + +These macros relate to the versioned, inline `nlohmann` namespace: + +- `NLOHMANN_JSON_NAMESPACE` evaluates to the full name of the `nlohmann` namespace (including the inline ABI namespace). +- `NLOHMANN_JSON_NAMESPACE_BEGIN` / `NLOHMANN_JSON_NAMESPACE_END` open and close the namespace (for example, to add specializations). +- `NLOHMANN_JSON_NAMESPACE_NO_VERSION`, when defined to `1`, omits the version component from the inline namespace. + +See the [`nlohmann` Namespace](https://json.nlohmann.me/features/namespace/index.md) page, and the full documentation of [`NLOHMANN_JSON_NAMESPACE`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace/index.md), [`NLOHMANN_JSON_NAMESPACE_BEGIN` / `NLOHMANN_JSON_NAMESPACE_END`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/index.md), and [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/index.md). + +## `NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)` + +This macro simplifies the serialization/deserialization of enum types. See [Specializing enum conversion](https://json.nlohmann.me/features/enum_conversion/index.md) for more information. + +See [full documentation of `NLOHMANN_JSON_SERIALIZE_ENUM`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md). + +A strict variant [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/index.md) throws an exception on undefined input instead of falling back to the first mapping. + +## `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, `NLOHMANN_JSON_VERSION_PATCH` + +These macros are defined by the library and contain the version numbers according to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). + +See [full documentation of `NLOHMANN_JSON_VERSION_MAJOR`, `NLOHMANN_JSON_VERSION_MINOR`, and `NLOHMANN_JSON_VERSION_PATCH`](https://json.nlohmann.me/api/macros/nlohmann_json_version_major/index.md). diff --git a/features/merge_patch.md b/features/merge_patch.md new file mode 100644 index 000000000..84e0ab02f --- /dev/null +++ b/features/merge_patch.md @@ -0,0 +1,20 @@ +# JSON Merge Patch + +The library supports JSON Merge Patch ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. +The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value. + +Instead of using [JSON Pointer](json_pointer.md) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified. + +??? example + + The following code shows how a JSON Merge Patch is applied to a JSON document. + + ```cpp + --8<-- "examples/merge_patch.cpp" + ``` + + Output: + + ```json + --8<-- "examples/merge_patch.output" + ``` diff --git a/features/merge_patch/index.html b/features/merge_patch/index.html index 2ac341020..e1eff72d8 100644 --- a/features/merge_patch/index.html +++ b/features/merge_patch/index.html @@ -50,4 +50,4 @@ ], "title": "Hello!" } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/merge_patch/index.md b/features/merge_patch/index.md new file mode 100644 index 000000000..9b0d9f4ad --- /dev/null +++ b/features/merge_patch/index.md @@ -0,0 +1,69 @@ +# JSON Merge Patch + +The library supports JSON Merge Patch ([RFC 7386](https://tools.ietf.org/html/rfc7386)) as a patch format. The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value. + +Instead of using [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) to specify values to be manipulated, it describes the changes using a syntax that closely mimics the document being modified. + +Example + +The following code shows how a JSON Merge Patch is applied to a JSON document. + +``` +#include +#include +#include // for std::setw + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // the original document + json document = R"({ + "title": "Goodbye!", + "author": { + "givenName": "John", + "familyName": "Doe" + }, + "tags": [ + "example", + "sample" + ], + "content": "This will be unchanged" + })"_json; + + // the patch + json patch = R"({ + "title": "Hello!", + "phoneNumber": "+01-123-456-7890", + "author": { + "familyName": null + }, + "tags": [ + "example" + ] + })"_json; + + // apply the patch + document.merge_patch(patch); + + // output original and patched document + std::cout << std::setw(4) << document << std::endl; +} +``` + +Output: + +``` +{ + "author": { + "givenName": "John" + }, + "content": "This will be unchanged", + "phoneNumber": "+01-123-456-7890", + "tags": [ + "example" + ], + "title": "Hello!" +} +``` diff --git a/features/modifying_values.md b/features/modifying_values.md new file mode 100644 index 000000000..23c0feb53 --- /dev/null +++ b/features/modifying_values.md @@ -0,0 +1,77 @@ +# Modifying values + +Once a JSON value exists, its content can be changed: elements can be added, replaced, merged, and removed. This page +gives an overview of the available operations. For read access, see [element access](element_access/index.md). + +## Adding to arrays + +New elements are appended to an array with [`push_back`](../api/basic_json/push_back.md) or constructed in place with +[`emplace_back`](../api/basic_json/emplace_back.md). If the value is `#!json null`, it is converted to an array first, so +these functions can also be used to build an array from scratch. + +```cpp +json j; // null +j.push_back(1); // [1] +j.push_back(2); // [1,2] +j.emplace_back(3); // [1,2,3] + +// operator+= is a shorthand for push_back +j += 4; // [1,2,3,4] +``` + +## Adding to objects + +The most common way to add or replace a member is [`operator[]`](element_access/unchecked_access.md), which inserts the +key if it does not exist yet: + +```cpp +json j; +j["name"] = "Mary"; // {"name":"Mary"} +j["name"] = "John"; // {"name":"John"} (replaced) +``` + +[`emplace`](../api/basic_json/emplace.md) inserts a member only if the key is not already present, and reports whether +the insertion happened — useful for "add if absent" semantics. + +## Merging objects + +To merge one object into another, [`update`](../api/basic_json/update.md) copies all members from another object, +overwriting existing keys (similar to Python's `dict.update`). This is the idiomatic way to combine two objects. + +??? example + + ```cpp + --8<-- "examples/update.cpp" + ``` + + Output: + + ```json + --8<-- "examples/update.output" + ``` + +For a recursive merge that follows [RFC 7386](https://tools.ietf.org/html/rfc7386), see +[JSON Merge Patch](merge_patch.md). To apply a sequence of well-defined edit operations, see +[JSON Patch](json_patch.md). + +## Removing elements + +Elements are removed with [`erase`](../api/basic_json/erase.md), which accepts an object key, an array index, or an +iterator. [`clear`](../api/basic_json/clear.md) empties a value while keeping its type, and +[`operator[]`](element_access/unchecked_access.md) combined with assignment can overwrite a value entirely. + +```cpp +json j = {{"a", 1}, {"b", 2}, {"c", 3}}; +j.erase("b"); // {"a":1,"c":3} + +json a = {1, 2, 3, 4}; +a.erase(1); // [1,3,4] (erase by index) +``` + +## See also + +- [`push_back`](../api/basic_json/push_back.md) / [`emplace_back`](../api/basic_json/emplace_back.md) - append to an array +- [`emplace`](../api/basic_json/emplace.md) - insert into an object if the key is absent +- [`update`](../api/basic_json/update.md) - merge objects +- [`erase`](../api/basic_json/erase.md) / [`clear`](../api/basic_json/clear.md) - remove elements +- [JSON Patch and Diff](json_patch.md) and [JSON Merge Patch](merge_patch.md) - structured modifications diff --git a/features/modifying_values/index.html b/features/modifying_values/index.html index 1f8f87da5..aec9a7fe2 100644 --- a/features/modifying_values/index.html +++ b/features/modifying_values/index.html @@ -54,4 +54,4 @@ json a = {1, 2, 3, 4}; a.erase(1); // [1,3,4] (erase by index) -

    See also

    \ No newline at end of file +

    See also

    \ No newline at end of file diff --git a/features/modifying_values/index.md b/features/modifying_values/index.md new file mode 100644 index 000000000..9663206e6 --- /dev/null +++ b/features/modifying_values/index.md @@ -0,0 +1,106 @@ +# Modifying values + +Once a JSON value exists, its content can be changed: elements can be added, replaced, merged, and removed. This page gives an overview of the available operations. For read access, see [element access](https://json.nlohmann.me/features/element_access/index.md). + +## Adding to arrays + +New elements are appended to an array with [`push_back`](https://json.nlohmann.me/api/basic_json/push_back/index.md) or constructed in place with [`emplace_back`](https://json.nlohmann.me/api/basic_json/emplace_back/index.md). If the value is `null`, it is converted to an array first, so these functions can also be used to build an array from scratch. + +``` +json j; // null +j.push_back(1); // [1] +j.push_back(2); // [1,2] +j.emplace_back(3); // [1,2,3] + +// operator+= is a shorthand for push_back +j += 4; // [1,2,3,4] +``` + +## Adding to objects + +The most common way to add or replace a member is [`operator[]`](https://json.nlohmann.me/features/element_access/unchecked_access/index.md), which inserts the key if it does not exist yet: + +``` +json j; +j["name"] = "Mary"; // {"name":"Mary"} +j["name"] = "John"; // {"name":"John"} (replaced) +``` + +[`emplace`](https://json.nlohmann.me/api/basic_json/emplace/index.md) inserts a member only if the key is not already present, and reports whether the insertion happened — useful for "add if absent" semantics. + +## Merging objects + +To merge one object into another, [`update`](https://json.nlohmann.me/api/basic_json/update/index.md) copies all members from another object, overwriting existing keys (similar to Python's `dict.update`). This is the idiomatic way to combine two objects. + +Example + +``` +#include +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + // create two JSON objects + json o1 = R"( {"color": "red", "price": 17.99, "names": {"de": "Flugzeug"}} )"_json; + json o2 = R"( {"color": "blue", "speed": 100, "names": {"en": "plane"}} )"_json; + json o3 = o1; + + // add all keys from o2 to o1 (updating "color", replacing "names") + o1.update(o2); + + // add all keys from o2 to o1 (updating "color", merging "names") + o3.update(o2, true); + + // output updated object o1 and o3 + std::cout << std::setw(2) << o1 << '\n'; + std::cout << std::setw(2) << o3 << '\n'; +} +``` + +Output: + +``` +{ + "color": "blue", + "names": { + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +{ + "color": "blue", + "names": { + "de": "Flugzeug", + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +``` + +For a recursive merge that follows [RFC 7386](https://tools.ietf.org/html/rfc7386), see [JSON Merge Patch](https://json.nlohmann.me/features/merge_patch/index.md). To apply a sequence of well-defined edit operations, see [JSON Patch](https://json.nlohmann.me/features/json_patch/index.md). + +## Removing elements + +Elements are removed with [`erase`](https://json.nlohmann.me/api/basic_json/erase/index.md), which accepts an object key, an array index, or an iterator. [`clear`](https://json.nlohmann.me/api/basic_json/clear/index.md) empties a value while keeping its type, and [`operator[]`](https://json.nlohmann.me/features/element_access/unchecked_access/index.md) combined with assignment can overwrite a value entirely. + +``` +json j = {{"a", 1}, {"b", 2}, {"c", 3}}; +j.erase("b"); // {"a":1,"c":3} + +json a = {1, 2, 3, 4}; +a.erase(1); // [1,3,4] (erase by index) +``` + +## See also + +- [`push_back`](https://json.nlohmann.me/api/basic_json/push_back/index.md) / [`emplace_back`](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) - append to an array +- [`emplace`](https://json.nlohmann.me/api/basic_json/emplace/index.md) - insert into an object if the key is absent +- [`update`](https://json.nlohmann.me/api/basic_json/update/index.md) - merge objects +- [`erase`](https://json.nlohmann.me/api/basic_json/erase/index.md) / [`clear`](https://json.nlohmann.me/api/basic_json/clear/index.md) - remove elements +- [JSON Patch and Diff](https://json.nlohmann.me/features/json_patch/index.md) and [JSON Merge Patch](https://json.nlohmann.me/features/merge_patch/index.md) - structured modifications diff --git a/features/modules.md b/features/modules.md new file mode 100644 index 000000000..53dc2b36f --- /dev/null +++ b/features/modules.md @@ -0,0 +1,40 @@ +# Modules + +This library has experimental support for C++ modules, introduced in C++20. The library can be imported by writing `import nlohmann.json;` instead of `#include `. + +Please be aware that the module is experimental and a full test is outstanding, and the exported symbols are subject to change. + +## Requirements +The `nlohmann.json` module requires that the build system is configured to build and resolve modules when imported. Obviously, as modules were introduced in C++20, this feature can only be used in C++20 and subsequent versions. + +To enable building the `nlohmann.json` module (which is not done by default), the macro `NLOHMANN_JSON_BUILD_MODULES` must be passed to the build system. + +## Example +When using modules rather than headers, the previous example for creating a `json` object through a JSON file, would instead be: +```cpp +import std; +import nlohmann.json; + +using json = nlohmann::json; + +// ... + +std::ifstream f("example.json"); +json data = json::parse(f); +``` + +## Modules do not export macros +It should be noted that as modules do not export macros, the `nlohmann.json` module will not export any macros. + +## Exported symbols +Only the following symbols are exported from `nlohmann.json`: + +- `nlohmann::adl_serializer` +- `nlohmann::basic_json` +- `nlohmann::json` +- `nlohmann::json_pointer` +- `nlohmann::ordered_json` +- `nlohmann::ordered_map` +- `nlohmann::to_string` +- `nlohmann::literals::json_literals::operator""_json` +- `nlohmann::literals::json_literals::operator""_json_pointer` diff --git a/features/modules/index.html b/features/modules/index.html index e265ff5a7..baaaee081 100644 --- a/features/modules/index.html +++ b/features/modules/index.html @@ -7,4 +7,4 @@ std::ifstream f("example.json"); json data = json::parse(f); -

    Modules do not export macros

    It should be noted that as modules do not export macros, the nlohmann.json module will not export any macros.

    Exported symbols

    Only the following symbols are exported from nlohmann.json:

    • nlohmann::adl_serializer
    • nlohmann::basic_json
    • nlohmann::json
    • nlohmann::json_pointer
    • nlohmann::ordered_json
    • nlohmann::ordered_map
    • nlohmann::to_string
    • nlohmann::literals::json_literals::operator""_json
    • nlohmann::literals::json_literals::operator""_json_pointer
    \ No newline at end of file +

    Modules do not export macros

    It should be noted that as modules do not export macros, the nlohmann.json module will not export any macros.

    Exported symbols

    Only the following symbols are exported from nlohmann.json:

    • nlohmann::adl_serializer
    • nlohmann::basic_json
    • nlohmann::json
    • nlohmann::json_pointer
    • nlohmann::ordered_json
    • nlohmann::ordered_map
    • nlohmann::to_string
    • nlohmann::literals::json_literals::operator""_json
    • nlohmann::literals::json_literals::operator""_json_pointer
    \ No newline at end of file diff --git a/features/modules/index.md b/features/modules/index.md new file mode 100644 index 000000000..3dfa209a0 --- /dev/null +++ b/features/modules/index.md @@ -0,0 +1,45 @@ +# Modules + +This library has experimental support for C++ modules, introduced in C++20. The library can be imported by writing `import nlohmann.json;` instead of `#include `. + +Please be aware that the module is experimental and a full test is outstanding, and the exported symbols are subject to change. + +## Requirements + +The `nlohmann.json` module requires that the build system is configured to build and resolve modules when imported. Obviously, as modules were introduced in C++20, this feature can only be used in C++20 and subsequent versions. + +To enable building the `nlohmann.json` module (which is not done by default), the macro `NLOHMANN_JSON_BUILD_MODULES` must be passed to the build system. + +## Example + +When using modules rather than headers, the previous example for creating a `json` object through a JSON file, would instead be: + +``` +import std; +import nlohmann.json; + +using json = nlohmann::json; + +// ... + +std::ifstream f("example.json"); +json data = json::parse(f); +``` + +## Modules do not export macros + +It should be noted that as modules do not export macros, the `nlohmann.json` module will not export any macros. + +## Exported symbols + +Only the following symbols are exported from `nlohmann.json`: + +- `nlohmann::adl_serializer` +- `nlohmann::basic_json` +- `nlohmann::json` +- `nlohmann::json_pointer` +- `nlohmann::ordered_json` +- `nlohmann::ordered_map` +- `nlohmann::to_string` +- `nlohmann::literals::json_literals::operator""_json` +- `nlohmann::literals::json_literals::operator""_json_pointer` diff --git a/features/namespace.md b/features/namespace.md new file mode 100644 index 000000000..5542c1f88 --- /dev/null +++ b/features/namespace.md @@ -0,0 +1,95 @@ +# `nlohmann` Namespace + +The 3.11.0 release introduced an +[inline namespace](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces) to allow different parts of +a codebase to safely use different versions of the JSON library as long as they never exchange instances of library +types. + +## Structure + +The complete default namespace name is derived as follows: + +- The root namespace is always `nlohmann`. +- The inline namespace starts with `json_abi` and is followed by several optional ABI tags according to the value of + these ABI-affecting macros, in order: + - [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) defined non-zero appends `_diag`. + - [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md) + defined non-zero appends `_ldvcmp`. +- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by + underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component) + below. + +For example, the namespace name for version 3.11.2 with `JSON_DIAGNOSTICS` defined to `1` is: + +```cpp +nlohmann::json_abi_diag_v3_11_2 +``` + +## Purpose + +Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different +definitions of [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This is illustrated in the diagram below. + +```mermaid +graph + json["nlohmann_json (v3.10.5)
    JSON_DIAGNOSTICS=0"] + json_diag["nlohmann_json (v3.10.5)
    JSON_DIAGNOSTICS=1"] + library["some library"] + app["application"] + + library --> json + app --> json_diag + app --> library +``` + +In releases prior to 3.11.0, mixing any version of the JSON library with different `JSON_DIAGNOSTICS` settings would +result in a crashing application. If `some_library` never passes instances of JSON library types to the application, +this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names. + +## Limitations + +Neither the compiler nor the linker will issue as much as a warning when translation units – intended to be linked +together and that include different versions and/or configurations of the JSON library – exchange and use library +types. + +There is an exception when forward declarations are used (i.e., when including `json_fwd.hpp`) in which case the linker +may complain about undefined references. + +## Disabling the version component + +Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and +recommends that all parts of a codebase exchanging library types be built with the same version. Users can, **at their +own risk**, disable the version component of the inline namespace, allowing different versions – but not +configurations – to be used in cases where the linker would otherwise output undefined reference errors. + +To do so, define [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](../api/macros/nlohmann_json_namespace_no_version.md) to `1`. + +This applies to version 3.11.2 and above only; versions 3.11.0 and 3.11.1 can apply the technique described in the next +section to emulate the effect of the `NLOHMANN_JSON_NAMESPACE_NO_VERSION` macro. + +!!! danger "Use at your own risk" + + Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect + behavior. You have been warned! + +## Disabling the inline namespace completely + +When interoperability with code using a pre-3.11.0 version of the library is required, users can, **at their own risk** +restore the old namespace layout by redefining +[`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](../api/macros/nlohmann_json_namespace_begin.md) as +follows: + +```cpp +#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann { +#define NLOHMANN_JSON_NAMESPACE_END } +``` + +!!! danger "Use at your own risk" + + Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You + have been warned! + +## Version history + +- Introduced inline namespace (`json_v3_11_0[_abi-tag]*`) in version 3.11.0. +- Changed structure of inline namespace in version 3.11.2. diff --git a/features/namespace/index.html b/features/namespace/index.html index c7d697eeb..91e1678e8 100644 --- a/features/namespace/index.html +++ b/features/namespace/index.html @@ -9,4 +9,4 @@ app --> json_diag app --> library

    In releases prior to 3.11.0, mixing any version of the JSON library with different JSON_DIAGNOSTICS settings would result in a crashing application. If some_library never passes instances of JSON library types to the application, this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names.

    Limitations

    Neither the compiler nor the linker will issue as much as a warning when translation units – intended to be linked together and that include different versions and/or configurations of the JSON library – exchange and use library types.

    There is an exception when forward declarations are used (i.e., when including json_fwd.hpp) in which case the linker may complain about undefined references.

    Disabling the version component

    Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and recommends that all parts of a codebase exchanging library types be built with the same version. Users can, at their own risk, disable the version component of the inline namespace, allowing different versions – but not configurations – to be used in cases where the linker would otherwise output undefined reference errors.

    To do so, define NLOHMANN_JSON_NAMESPACE_NO_VERSION to 1.

    This applies to version 3.11.2 and above only; versions 3.11.0 and 3.11.1 can apply the technique described in the next section to emulate the effect of the NLOHMANN_JSON_NAMESPACE_NO_VERSION macro.

    Use at your own risk

    Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned!

    Disabling the inline namespace completely

    When interoperability with code using a pre-3.11.0 version of the library is required, users can, at their own risk restore the old namespace layout by redefining NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END as follows:

    #define NLOHMANN_JSON_NAMESPACE_BEGIN  namespace nlohmann {
     #define NLOHMANN_JSON_NAMESPACE_END    }
    -

    Use at your own risk

    Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned!

    Version history

    • Introduced inline namespace (json_v3_11_0[_abi-tag]*) in version 3.11.0.
    • Changed structure of inline namespace in version 3.11.2.
    \ No newline at end of file +

    Use at your own risk

    Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned!

    Version history

    • Introduced inline namespace (json_v3_11_0[_abi-tag]*) in version 3.11.0.
    • Changed structure of inline namespace in version 3.11.2.
    \ No newline at end of file diff --git a/features/namespace/index.md b/features/namespace/index.md new file mode 100644 index 000000000..cfc360777 --- /dev/null +++ b/features/namespace/index.md @@ -0,0 +1,73 @@ +# `nlohmann` Namespace + +The 3.11.0 release introduced an [inline namespace](https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces) to allow different parts of a codebase to safely use different versions of the JSON library as long as they never exchange instances of library types. + +## Structure + +The complete default namespace name is derived as follows: + +- The root namespace is always `nlohmann`. +- The inline namespace starts with `json_abi` and is followed by several optional ABI tags according to the value of these ABI-affecting macros, in order: + - [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) defined non-zero appends `_diag`. + - [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/index.md) defined non-zero appends `_ldvcmp`. +- The inline namespace ends with the suffix `_v` followed by the 3 components of the version number separated by underscores. To omit the version component, see [Disabling the version component](#disabling-the-version-component) below. + +For example, the namespace name for version 3.11.2 with `JSON_DIAGNOSTICS` defined to `1` is: + +``` +nlohmann::json_abi_diag_v3_11_2 +``` + +## Purpose + +Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different definitions of [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md). This is illustrated in the diagram below. + +``` +graph + json["nlohmann_json (v3.10.5)
    JSON_DIAGNOSTICS=0"] + json_diag["nlohmann_json (v3.10.5)
    JSON_DIAGNOSTICS=1"] + library["some library"] + app["application"] + + library --> json + app --> json_diag + app --> library +``` + +In releases prior to 3.11.0, mixing any version of the JSON library with different `JSON_DIAGNOSTICS` settings would result in a crashing application. If `some_library` never passes instances of JSON library types to the application, this scenario became safe in version 3.11.0 and above due to the inline namespace yielding distinct symbol names. + +## Limitations + +Neither the compiler nor the linker will issue as much as a warning when translation units – intended to be linked together and that include different versions and/or configurations of the JSON library – exchange and use library types. + +There is an exception when forward declarations are used (i.e., when including `json_fwd.hpp`) in which case the linker may complain about undefined references. + +## Disabling the version component + +Different versions are not necessarily ABI-incompatible, but the project does not actively track changes in the ABI and recommends that all parts of a codebase exchanging library types be built with the same version. Users can, **at their own risk**, disable the version component of the inline namespace, allowing different versions – but not configurations – to be used in cases where the linker would otherwise output undefined reference errors. + +To do so, define [`NLOHMANN_JSON_NAMESPACE_NO_VERSION`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/index.md) to `1`. + +This applies to version 3.11.2 and above only; versions 3.11.0 and 3.11.1 can apply the technique described in the next section to emulate the effect of the `NLOHMANN_JSON_NAMESPACE_NO_VERSION` macro. + +Use at your own risk + +Disabling the namespace version component and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned! + +## Disabling the inline namespace completely + +When interoperability with code using a pre-3.11.0 version of the library is required, users can, **at their own risk** restore the old namespace layout by redefining [`NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/index.md) as follows: + +``` +#define NLOHMANN_JSON_NAMESPACE_BEGIN namespace nlohmann { +#define NLOHMANN_JSON_NAMESPACE_END } +``` + +Use at your own risk + +Overriding the namespace and mixing ABI-incompatible versions will result in crashes or incorrect behavior. You have been warned! + +## Version history + +- Introduced inline namespace (`json_v3_11_0[_abi-tag]*`) in version 3.11.0. +- Changed structure of inline namespace in version 3.11.2. diff --git a/features/object_order.md b/features/object_order.md new file mode 100644 index 000000000..ac5eb7beb --- /dev/null +++ b/features/object_order.md @@ -0,0 +1,109 @@ +# Object Order + +The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys. + +## Default behavior: sort keys + +The default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**. + +??? example + + ```cpp + #include + #include + + using json = nlohmann::json; + + int main() + { + json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + std::cout << j.dump(2) << '\n'; + } + ``` + + Output: + + ```json + { + "one": 1, + "three": 3, + "two": 2 + } + ``` + +## Alternative behavior: preserve insertion order + +If you do want to preserve the **insertion order**, you can use the type [`nlohmann::ordered_json`](../api/ordered_json.md). + +??? example + + ```cpp + --8<-- "examples/ordered_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/ordered_json.output" + ``` + +Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)). + +### Notes on parsing + +Note that you also need to call the right [`parse`](../api/basic_json/parse.md) function when reading from a file. +Assume file `input.json` contains the JSON object above: + +```json +{ + "one": 1, + "two": 2, + "three": 3 +} +``` + +!!! success "Right way" + + The following code correctly calls the `parse` function from `nlohmann::ordered_json`: + + ```cpp + std::ifstream i("input.json"); + auto j = nlohmann::ordered_json::parse(i); + std::cout << j.dump(2) << std::endl; + ``` + + The output will be: + + ```json + { + "one": 1, + "two": 2, + "three": 3 + } + ``` + +??? failure "Wrong way" + + The following code incorrectly calls the `parse` function from `nlohmann::json` which does not preserve the + insertion order, but sorts object keys. Assigning the result to `nlohmann::ordered_json` compiles, but does not + restore the order from the input file. + + ```cpp + std::ifstream i("input.json"); + nlohmann::ordered_json j = nlohmann::json::parse(i); + std::cout << j.dump(2) << std::endl; + ``` + + The output will be: + + ```json + { + "one": 1, + "three": 3, + "two": 2 + } + ``` diff --git a/features/object_order/index.html b/features/object_order/index.html index 20c470cc5..4fb590428 100644 --- a/features/object_order/index.html +++ b/features/object_order/index.html @@ -57,4 +57,4 @@ "three": 3, "two": 2 } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/object_order/index.md b/features/object_order/index.md new file mode 100644 index 000000000..18aba9b59 --- /dev/null +++ b/features/object_order/index.md @@ -0,0 +1,123 @@ +# Object Order + +The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys. + +## Default behavior: sort keys + +The default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**. + +Example + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + std::cout << j.dump(2) << '\n'; +} +``` + +Output: + +``` +{ + "one": 1, + "three": 3, + "two": 2 +} +``` + +## Alternative behavior: preserve insertion order + +If you do want to preserve the **insertion order**, you can use the type [`nlohmann::ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md). + +Example + +``` +#include +#include + +using ordered_json = nlohmann::ordered_json; + +int main() +{ + ordered_json j; + j["one"] = 1; + j["two"] = 2; + j["three"] = 3; + + std::cout << j.dump(2) << '\n'; +} +``` + +Output: + +``` +{ + "one": 1, + "two": 2, + "three": 3 +} +``` + +Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)). + +### Notes on parsing + +Note that you also need to call the right [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function when reading from a file. Assume file `input.json` contains the JSON object above: + +``` +{ + "one": 1, + "two": 2, + "three": 3 +} +``` + +Right way + +The following code correctly calls the `parse` function from `nlohmann::ordered_json`: + +``` +std::ifstream i("input.json"); +auto j = nlohmann::ordered_json::parse(i); +std::cout << j.dump(2) << std::endl; +``` + +The output will be: + +``` +{ + "one": 1, + "two": 2, + "three": 3 +} +``` + +Wrong way + +The following code incorrectly calls the `parse` function from `nlohmann::json` which does not preserve the insertion order, but sorts object keys. Assigning the result to `nlohmann::ordered_json` compiles, but does not restore the order from the input file. + +``` +std::ifstream i("input.json"); +nlohmann::ordered_json j = nlohmann::json::parse(i); +std::cout << j.dump(2) << std::endl; +``` + +The output will be: + +``` +{ + "one": 1, + "three": 3, + "two": 2 +} +``` diff --git a/features/parsing.md b/features/parsing.md new file mode 100644 index 000000000..c3cb88f63 --- /dev/null +++ b/features/parsing.md @@ -0,0 +1,61 @@ +# Parsing + +This library can create a JSON value from a wide range of inputs. This page gives an overview of the available parsing +functions and how they behave; the linked pages go into more detail. + +## Input + +The [`parse`](../../api/basic_json/parse.md) function reads a JSON value from an input. The input can be + +- a string (`#!cpp std::string`, C string, or string literal), +- a `#!cpp std::istream` (e.g., an `#!cpp std::ifstream` reading from a file), +- a `#!cpp FILE*` pointer, +- a pair of iterators over a contiguous range (e.g., a `#!cpp std::vector`), or +- a contiguous container. + +```cpp +// parse from a string +json j = json::parse(R"({"happy": true, "pi": 3.141})"); + +// parse from a file +std::ifstream f("example.json"); +json data = json::parse(f); +``` + +The input must be encoded in UTF-8; other encodings are not supported. A single input may contain only one JSON value. +Inputs consisting of multiple values separated by newlines are handled by the [JSON Lines](json_lines.md) format. + +By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the `parse` +function — see [comments](../comments.md) and [trailing commas](../trailing_commas.md). + +## SAX vs. DOM parsing + +The library offers two parsing models: + +- **DOM parsing** (the default): the complete input is read and stored as an in-memory `basic_json` value that can be + traversed and modified freely. This is what [`parse`](../../api/basic_json/parse.md) does, and it is the right choice + for most use cases. +- **SAX parsing**: instead of building a value, the parser reports events (such as "a string was read" or "an object + started") to a handler that you implement. This avoids building the full value in memory and is useful for very large + inputs or when you only need to extract parts of the input. See the [SAX interface](sax_interface.md) for details and + [`sax_parse`](../../api/basic_json/sax_parse.md) for the API. + +You can influence a DOM parse without switching to the SAX interface by passing a +[parser callback](parser_callbacks.md), which is called during parsing and can, for example, discard parts of the input. + +## Exceptions + +When the input is not valid JSON, the `parse` function throws an exception by default. If exceptions are undesired or +unavailable, the parser can instead return a discarded value, or [`accept`](../../api/basic_json/accept.md) can be used +to only check whether an input is valid JSON. See [parsing and exceptions](parse_exceptions.md) for the available +options. + +## See also + +- [`parse`](../../api/basic_json/parse.md) - deserialize from a compatible input +- [`accept`](../../api/basic_json/accept.md) - check if the input is valid JSON +- [`sax_parse`](../../api/basic_json/sax_parse.md) - generate SAX events +- [JSON Lines](json_lines.md) - parse newline-delimited JSON +- [parser callbacks](parser_callbacks.md) - influence the parsing by a callback function +- [SAX interface](sax_interface.md) - implement a custom SAX handler +- [parsing and exceptions](parse_exceptions.md) - control error handling diff --git a/features/parsing/index.html b/features/parsing/index.html index 9540a0277..def5c0998 100644 --- a/features/parsing/index.html +++ b/features/parsing/index.html @@ -4,4 +4,4 @@ // parse from a file std::ifstream f("example.json"); json data = json::parse(f); -

    The input must be encoded in UTF-8; other encodings are not supported. A single input may contain only one JSON value. Inputs consisting of multiple values separated by newlines are handled by the JSON Lines format.

    By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the parse function — see comments and trailing commas.

    SAX vs. DOM parsing

    The library offers two parsing models:

    • DOM parsing (the default): the complete input is read and stored as an in-memory basic_json value that can be traversed and modified freely. This is what parse does, and it is the right choice for most use cases.
    • SAX parsing: instead of building a value, the parser reports events (such as "a string was read" or "an object started") to a handler that you implement. This avoids building the full value in memory and is useful for very large inputs or when you only need to extract parts of the input. See the SAX interface for details and sax_parse for the API.

    You can influence a DOM parse without switching to the SAX interface by passing a parser callback, which is called during parsing and can, for example, discard parts of the input.

    Exceptions

    When the input is not valid JSON, the parse function throws an exception by default. If exceptions are undesired or unavailable, the parser can instead return a discarded value, or accept can be used to only check whether an input is valid JSON. See parsing and exceptions for the available options.

    See also

    \ No newline at end of file +

    The input must be encoded in UTF-8; other encodings are not supported. A single input may contain only one JSON value. Inputs consisting of multiple values separated by newlines are handled by the JSON Lines format.

    By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the parse function — see comments and trailing commas.

    SAX vs. DOM parsing

    The library offers two parsing models:

    • DOM parsing (the default): the complete input is read and stored as an in-memory basic_json value that can be traversed and modified freely. This is what parse does, and it is the right choice for most use cases.
    • SAX parsing: instead of building a value, the parser reports events (such as "a string was read" or "an object started") to a handler that you implement. This avoids building the full value in memory and is useful for very large inputs or when you only need to extract parts of the input. See the SAX interface for details and sax_parse for the API.

    You can influence a DOM parse without switching to the SAX interface by passing a parser callback, which is called during parsing and can, for example, discard parts of the input.

    Exceptions

    When the input is not valid JSON, the parse function throws an exception by default. If exceptions are undesired or unavailable, the parser can instead return a discarded value, or accept can be used to only check whether an input is valid JSON. See parsing and exceptions for the available options.

    See also

    \ No newline at end of file diff --git a/features/parsing/index.md b/features/parsing/index.md new file mode 100644 index 000000000..1712b496b --- /dev/null +++ b/features/parsing/index.md @@ -0,0 +1,49 @@ +# Parsing + +This library can create a JSON value from a wide range of inputs. This page gives an overview of the available parsing functions and how they behave; the linked pages go into more detail. + +## Input + +The [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function reads a JSON value from an input. The input can be + +- a string (`std::string`, C string, or string literal), +- a `std::istream` (e.g., an `std::ifstream` reading from a file), +- a `FILE*` pointer, +- a pair of iterators over a contiguous range (e.g., a `std::vector`), or +- a contiguous container. + +``` +// parse from a string +json j = json::parse(R"({"happy": true, "pi": 3.141})"); + +// parse from a file +std::ifstream f("example.json"); +json data = json::parse(f); +``` + +The input must be encoded in UTF-8; other encodings are not supported. A single input may contain only one JSON value. Inputs consisting of multiple values separated by newlines are handled by the [JSON Lines](https://json.nlohmann.me/features/parsing/json_lines/index.md) format. + +By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the `parse` function — see [comments](https://json.nlohmann.me/features/comments/index.md) and [trailing commas](https://json.nlohmann.me/features/trailing_commas/index.md). + +## SAX vs. DOM parsing + +The library offers two parsing models: + +- **DOM parsing** (the default): the complete input is read and stored as an in-memory `basic_json` value that can be traversed and modified freely. This is what [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) does, and it is the right choice for most use cases. +- **SAX parsing**: instead of building a value, the parser reports events (such as "a string was read" or "an object started") to a handler that you implement. This avoids building the full value in memory and is useful for very large inputs or when you only need to extract parts of the input. See the [SAX interface](https://json.nlohmann.me/features/parsing/sax_interface/index.md) for details and [`sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) for the API. + +You can influence a DOM parse without switching to the SAX interface by passing a [parser callback](https://json.nlohmann.me/features/parsing/parser_callbacks/index.md), which is called during parsing and can, for example, discard parts of the input. + +## Exceptions + +When the input is not valid JSON, the `parse` function throws an exception by default. If exceptions are undesired or unavailable, the parser can instead return a discarded value, or [`accept`](https://json.nlohmann.me/api/basic_json/accept/index.md) can be used to only check whether an input is valid JSON. See [parsing and exceptions](https://json.nlohmann.me/features/parsing/parse_exceptions/index.md) for the available options. + +## See also + +- [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) - deserialize from a compatible input +- [`accept`](https://json.nlohmann.me/api/basic_json/accept/index.md) - check if the input is valid JSON +- [`sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) - generate SAX events +- [JSON Lines](https://json.nlohmann.me/features/parsing/json_lines/index.md) - parse newline-delimited JSON +- [parser callbacks](https://json.nlohmann.me/features/parsing/parser_callbacks/index.md) - influence the parsing by a callback function +- [SAX interface](https://json.nlohmann.me/features/parsing/sax_interface/index.md) - implement a custom SAX handler +- [parsing and exceptions](https://json.nlohmann.me/features/parsing/parse_exceptions/index.md) - control error handling diff --git a/features/parsing/json_lines.md b/features/parsing/json_lines.md new file mode 100644 index 000000000..659d31792 --- /dev/null +++ b/features/parsing/json_lines.md @@ -0,0 +1,49 @@ +# JSON Lines + +The [JSON Lines](https://jsonlines.org) format is a text format of newline-delimited JSON. In particular: + +1. The input must be UTF-8 encoded. +2. Every line must be a valid JSON value. +3. The line separator must be `\n`. As `\r` is silently ignored, `\r\n` is also supported. +4. The final character may be `\n`, but is not required to be one. + +!!! example "JSON Text example" + + ```json + {"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]} + {"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]} + {"name": "May", "wins": []} + {"name": "Deloise", "wins": [["three of a kind", "5♣"]]} + ``` + +JSON Lines input with more than one value is treated as invalid JSON by the [`parse`](../../api/basic_json/parse.md) or +[`accept`](../../api/basic_json/accept.md) functions. To process it line by line, functions like +[`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) can be used: + +!!! example "Example: Parse JSON Text input line by line" + + The example below demonstrates how JSON Lines can be processed. + + ```cpp + --8<-- "examples/json_lines.cpp" + ``` + + Output: + + ```json + --8<-- "examples/json_lines.output" + ``` + +!!! warning "Note" + + Using [`operator>>`](../../api/operator_gtgt.md) like + + ```cpp + json j; + while (input >> j) + { + std::cout << j << std::endl; + } + ``` + + with a JSON Lines input does not work, because the parser will try to parse one value after the last one. diff --git a/features/parsing/json_lines/index.html b/features/parsing/json_lines/index.html index 49371789a..e3d5de96c 100644 --- a/features/parsing/json_lines/index.html +++ b/features/parsing/json_lines/index.html @@ -33,4 +33,4 @@ { std::cout << j << std::endl; } -

    with a JSON Lines input does not work, because the parser will try to parse one value after the last one.

    \ No newline at end of file +

    with a JSON Lines input does not work, because the parser will try to parse one value after the last one.

    \ No newline at end of file diff --git a/features/parsing/json_lines/index.md b/features/parsing/json_lines/index.md new file mode 100644 index 000000000..0be8e6afc --- /dev/null +++ b/features/parsing/json_lines/index.md @@ -0,0 +1,71 @@ +# JSON Lines + +The [JSON Lines](https://jsonlines.org) format is a text format of newline-delimited JSON. In particular: + +1. The input must be UTF-8 encoded. +1. Every line must be a valid JSON value. +1. The line separator must be `\n`. As `\r` is silently ignored, `\r\n` is also supported. +1. The final character may be `\n`, but is not required to be one. + +JSON Text example + +``` +{"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]} +{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]} +{"name": "May", "wins": []} +{"name": "Deloise", "wins": [["three of a kind", "5♣"]]} +``` + +JSON Lines input with more than one value is treated as invalid JSON by the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) or [`accept`](https://json.nlohmann.me/api/basic_json/accept/index.md) functions. To process it line by line, functions like [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) can be used: + +Example: Parse JSON Text input line by line + +The example below demonstrates how JSON Lines can be processed. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // JSON Lines (see https://jsonlines.org) + std::stringstream input; + input << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]} +{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]} +{"name": "May", "wins": []} +{"name": "Deloise", "wins": [["three of a kind", "5♣"]]} +)"; + + std::string line; + while (std::getline(input, line)) + { + std::cout << json::parse(line) << std::endl; + } +} +``` + +Output: + +``` +{"name":"Gilbert","wins":[["straight","7♣"],["one pair","10♥"]]} +{"name":"Alexa","wins":[["two pair","4♠"],["two pair","9♠"]]} +{"name":"May","wins":[]} +{"name":"Deloise","wins":[["three of a kind","5♣"]]} +``` + +Note + +Using [`operator>>`](https://json.nlohmann.me/api/operator_gtgt/index.md) like + +``` +json j; +while (input >> j) +{ + std::cout << j << std::endl; +} +``` + +with a JSON Lines input does not work, because the parser will try to parse one value after the last one. diff --git a/features/parsing/parse_exceptions.md b/features/parsing/parse_exceptions.md new file mode 100644 index 000000000..25b4768ff --- /dev/null +++ b/features/parsing/parse_exceptions.md @@ -0,0 +1,121 @@ +# Parsing and Exceptions + +When the input is not valid JSON, an exception of type [`parse_error`](../../home/exceptions.md#parse-errors) is thrown. +This exception contains the position in the input where the error occurred, together with a diagnostic message and the +last read input token. The exceptions page contains a +[list of examples for parse error exceptions](../../home/exceptions.md#parse-errors). In case you process untrusted +input, always enclose your code with a `#!cpp try`/`#!cpp catch` block, like + +```cpp +json j; +try +{ + j = json::parse(my_input); +} +catch (json::parse_error& ex) +{ + std::cerr << "parse error at byte " << ex.byte << std::endl; +} +``` + +In case exceptions are undesired or not supported by the environment, there are different ways to proceed: + + +## Switch off exceptions + +The `parse()` function accepts a `#!cpp bool` parameter `allow_exceptions` which controls whether an exception is +thrown when a parse error occurs (`#!cpp true`, default) or whether a discarded value should be returned +(`#!cpp false`). + +```cpp +json j = json::parse(my_input, nullptr, false); +if (j.is_discarded()) +{ + std::cerr << "parse error" << std::endl; +} +``` + +Note there is no diagnostic information available in this scenario. + +## Use accept() function + +Alternatively, function `accept()` can be used which does not return a `json` value, but a `#!cpp bool` indicating +whether the input is valid JSON. + +```cpp +if (!json::accept(my_input)) +{ + std::cerr << "parse error" << std::endl; +} +``` + +Again, there is no diagnostic information available. + + +## User-defined SAX interface + +Finally, you can implement the [SAX interface](sax_interface.md) and decide what should happen in case of a parse error. + +This function has the following interface: + +```cpp +bool parse_error(std::size_t position, + const std::string& last_token, + const json::exception& ex); +``` + +The return value indicates whether the parsing should continue, so the function should usually return `#!cpp false`. + +??? example + + ```cpp + #include + #include + + using json = nlohmann::json; + + class sax_no_exception : public nlohmann::detail::json_sax_dom_parser + { + public: + sax_no_exception(json& j) + : nlohmann::detail::json_sax_dom_parser(j, false) + {} + + bool parse_error(std::size_t position, + const std::string& last_token, + const json::exception& ex) + { + std::cerr << "parse error at input byte " << position << "\n" + << ex.what() << "\n" + << "last read: \"" << last_token << "\"" + << std::endl; + return false; + } + }; + + int main() + { + std::string myinput = "[1,2,3,]"; + + json result; + sax_no_exception sax(result); + + bool parse_result = json::sax_parse(myinput, &sax); + if (!parse_result) + { + std::cerr << "parsing unsuccessful!" << std::endl; + } + + std::cout << "parsed value: " << result << std::endl; + } + ``` + + Output: + + ``` + parse error at input byte 8 + [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal + last read: "3,]" + parsing unsuccessful! + parsed value: [1,2,3] + ``` diff --git a/features/parsing/parse_exceptions/index.html b/features/parsing/parse_exceptions/index.html index b924d3c20..d489d8f3b 100644 --- a/features/parsing/parse_exceptions/index.html +++ b/features/parsing/parse_exceptions/index.html @@ -63,4 +63,4 @@ last read: "3,]" parsing unsuccessful! parsed value: [1,2,3] -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/parsing/parse_exceptions/index.md b/features/parsing/parse_exceptions/index.md new file mode 100644 index 000000000..db2c1c789 --- /dev/null +++ b/features/parsing/parse_exceptions/index.md @@ -0,0 +1,112 @@ +# Parsing and Exceptions + +When the input is not valid JSON, an exception of type [`parse_error`](https://json.nlohmann.me/home/exceptions/#parse-errors) is thrown. This exception contains the position in the input where the error occurred, together with a diagnostic message and the last read input token. The exceptions page contains a [list of examples for parse error exceptions](https://json.nlohmann.me/home/exceptions/#parse-errors). In case you process untrusted input, always enclose your code with a `try`/`catch` block, like + +``` +json j; +try +{ + j = json::parse(my_input); +} +catch (json::parse_error& ex) +{ + std::cerr << "parse error at byte " << ex.byte << std::endl; +} +``` + +In case exceptions are undesired or not supported by the environment, there are different ways to proceed: + +## Switch off exceptions + +The `parse()` function accepts a `bool` parameter `allow_exceptions` which controls whether an exception is thrown when a parse error occurs (`true`, default) or whether a discarded value should be returned (`false`). + +``` +json j = json::parse(my_input, nullptr, false); +if (j.is_discarded()) +{ + std::cerr << "parse error" << std::endl; +} +``` + +Note there is no diagnostic information available in this scenario. + +## Use accept() function + +Alternatively, function `accept()` can be used which does not return a `json` value, but a `bool` indicating whether the input is valid JSON. + +``` +if (!json::accept(my_input)) +{ + std::cerr << "parse error" << std::endl; +} +``` + +Again, there is no diagnostic information available. + +## User-defined SAX interface + +Finally, you can implement the [SAX interface](https://json.nlohmann.me/features/parsing/sax_interface/index.md) and decide what should happen in case of a parse error. + +This function has the following interface: + +``` +bool parse_error(std::size_t position, + const std::string& last_token, + const json::exception& ex); +``` + +The return value indicates whether the parsing should continue, so the function should usually return `false`. + +Example + +``` +#include +#include + +using json = nlohmann::json; + +class sax_no_exception : public nlohmann::detail::json_sax_dom_parser +{ + public: + sax_no_exception(json& j) + : nlohmann::detail::json_sax_dom_parser(j, false) + {} + + bool parse_error(std::size_t position, + const std::string& last_token, + const json::exception& ex) + { + std::cerr << "parse error at input byte " << position << "\n" + << ex.what() << "\n" + << "last read: \"" << last_token << "\"" + << std::endl; + return false; + } +}; + +int main() +{ + std::string myinput = "[1,2,3,]"; + + json result; + sax_no_exception sax(result); + + bool parse_result = json::sax_parse(myinput, &sax); + if (!parse_result) + { + std::cerr << "parsing unsuccessful!" << std::endl; + } + + std::cout << "parsed value: " << result << std::endl; +} +``` + +Output: + +``` +parse error at input byte 8 +[json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal +last read: "3,]" +parsing unsuccessful! +parsed value: [1,2,3] +``` diff --git a/features/parsing/parser_callbacks.md b/features/parsing/parser_callbacks.md new file mode 100644 index 000000000..ef076d126 --- /dev/null +++ b/features/parsing/parser_callbacks.md @@ -0,0 +1,83 @@ +# Parser Callbacks + +## Overview + +With a parser callback function, the result of parsing a JSON text can be influenced. When passed to `parse`, it is +called on certain events (passed as `parse_event_t` via parameter `event`) with a set recursion depth `depth` and +context JSON value `parsed`. The return value of the callback function is a boolean indicating whether the element that +emitted the callback shall be kept or not. + +The type of the callback function is: + +```cpp +template +using parser_callback_t = + std::function; +``` + + +## Callback event types + +We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following +table describes the values of the parameters `depth`, `event`, and `parsed`. + +| parameter `event` | description | parameter `depth` | parameter `parsed` | +|-------------------------------|-----------------------------------------------------------|-------------------------------------------|----------------------------------| +| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded | +| `parse_event_t::key` | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key | +| `parse_event_t::object_end` | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object | +| `parse_event_t::array_start` | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded | +| `parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array | +| `parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value | + +??? example + + When parsing the following JSON text, + + ```json + { + "name": "Berlin", + "location": [ + 52.519444, + 13.406667 + ] + } + ``` + + these calls are made to the callback function: + + | event | depth | parsed | + | -------------- | ----- | ------ | + | `object_start` | 0 | *discarded* | + | `key` | 1 | `#!json "name"` | + | `value` | 1 | `#!json "Berlin"` | + | `key` | 1 | `#!json "location"` | + | `array_start` | 1 | *discarded* | + | `value` | 2 | `#!json 52.519444` | + | `value` | 2 | `#!json 13.406667` | + | `array_end` | 1 | `#!json [52.519444,13.406667]` | + | `object_end` | 0 | `#!json {"location":[52.519444,13.406667],"name":"Berlin"}` | + +## Return value + +Discarding a value (i.e., returning `#!c false`) has different effects depending on the context in which the function +was called: + +- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never + read. +- In case a value outside a structured type is skipped, it is replaced with `#!json null`. This case happens if the + top-level element is skipped. + +??? example + + The example below demonstrates the `parse()` function with and without callback function. + + ```cpp + --8<-- "examples/parse__string__parser_callback_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/parse__string__parser_callback_t.output" + ``` diff --git a/features/parsing/parser_callbacks/index.html b/features/parsing/parser_callbacks/index.html index ea3d975c0..ce40f2e3d 100644 --- a/features/parsing/parser_callbacks/index.html +++ b/features/parsing/parser_callbacks/index.html @@ -90,4 +90,4 @@ "Width": 800 } } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/parsing/parser_callbacks/index.md b/features/parsing/parser_callbacks/index.md new file mode 100644 index 000000000..ff43e1a74 --- /dev/null +++ b/features/parsing/parser_callbacks/index.md @@ -0,0 +1,155 @@ +# Parser Callbacks + +## Overview + +With a parser callback function, the result of parsing a JSON text can be influenced. When passed to `parse`, it is called on certain events (passed as `parse_event_t` via parameter `event`) with a set recursion depth `depth` and context JSON value `parsed`. The return value of the callback function is a boolean indicating whether the element that emitted the callback shall be kept or not. + +The type of the callback function is: + +``` +template +using parser_callback_t = + std::function; +``` + +## Callback event types + +We distinguish six scenarios (determined by the event type) in which the callback function can be called. The following table describes the values of the parameters `depth`, `event`, and `parsed`. + +| parameter `event` | description | parameter `depth` | parameter `parsed` | +| ----------------------------- | --------------------------------------------------------- | ----------------------------------------- | -------------------------------- | +| `parse_event_t::object_start` | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded | +| `parse_event_t::key` | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key | +| `parse_event_t::object_end` | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object | +| `parse_event_t::array_start` | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded | +| `parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array | +| `parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value | + +Example + +When parsing the following JSON text, + +``` +{ + "name": "Berlin", + "location": [ + 52.519444, + 13.406667 + ] +} +``` + +these calls are made to the callback function: + +| event | depth | parsed | +| -------------- | ----- | ---------------------------------------------------- | +| `object_start` | 0 | *discarded* | +| `key` | 1 | `"name"` | +| `value` | 1 | `"Berlin"` | +| `key` | 1 | `"location"` | +| `array_start` | 1 | *discarded* | +| `value` | 2 | `52.519444` | +| `value` | 2 | `13.406667` | +| `array_end` | 1 | `[52.519444,13.406667]` | +| `object_end` | 0 | `{"location":[52.519444,13.406667],"name":"Berlin"}` | + +## Return value + +Discarding a value (i.e., returning `false`) has different effects depending on the context in which the function was called: + +- Discarded values in structured types are skipped. That is, the parser will behave as if the discarded value was never read. +- In case a value outside a structured type is skipped, it is replaced with `null`. This case happens if the top-level element is skipped. + +Example + +The example below demonstrates the `parse()` function with and without callback function. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // a JSON text + auto text = R"( + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": 100 + }, + "Animated" : false, + "IDs": [116, 943, 234, 38793] + } + } + )"; + + // parse and serialize JSON + json j_complete = json::parse(text); + std::cout << std::setw(4) << j_complete << "\n\n"; + + // define parser callback + json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed) + { + // skip object elements with key "Thumbnail" + if (event == json::parse_event_t::key and parsed == json("Thumbnail")) + { + return false; + } + else + { + return true; + } + }; + + // parse (with callback) and serialize JSON + json j_filtered = json::parse(text, cb); + std::cout << std::setw(4) << j_filtered << '\n'; +} +``` + +Output: + +``` +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Thumbnail": { + "Height": 125, + "Url": "http://www.example.com/image/481989943", + "Width": 100 + }, + "Title": "View from 15th Floor", + "Width": 800 + } +} + +{ + "Image": { + "Animated": false, + "Height": 600, + "IDs": [ + 116, + 943, + 234, + 38793 + ], + "Title": "View from 15th Floor", + "Width": 800 + } +} +``` diff --git a/features/parsing/sax_interface.md b/features/parsing/sax_interface.md new file mode 100644 index 000000000..cfea680a4 --- /dev/null +++ b/features/parsing/sax_interface.md @@ -0,0 +1,76 @@ +# SAX Interface + +The library uses a SAX-like interface with the following functions: + +```mermaid +classDiagram + +class sax_t ["json::sax_t"] { + <> + +bool null()* + + +bool boolean(bool val)* + + +bool number_integer(number_integer_t val)* + +bool number_unsigned(number_unsigned_t val)* + + +bool number_float(number_float_t val, const string_t& s)* + + +bool string(string_t& val)* + +bool binary(binary_t& val)* + + +bool start_object(std::size_t elements)* + +bool end_object()* + +bool start_array(std::size_t elements)* + +bool end_array()* + +bool key(string_t& val)* + + +bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex)* +} +``` + +```cpp +// called when null is parsed +bool null(); + +// called when a boolean is parsed; value is passed +bool boolean(bool val); + +// called when a signed or unsigned integer number is parsed; value is passed +bool number_integer(number_integer_t val); +bool number_unsigned(number_unsigned_t val); + +// called when a floating-point number is parsed; value and original string is passed +bool number_float(number_float_t val, const string_t& s); + +// called when a string is parsed; value is passed and can be safely moved away +bool string(string_t& val); +// called when a binary value is parsed; value is passed and can be safely moved away +bool binary(binary_t& val); + +// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known) +bool start_object(std::size_t elements); +bool end_object(); +bool start_array(std::size_t elements); +bool end_array(); +// called when an object key is parsed; value is passed and can be safely moved away +bool key(string_t& val); + +// called when a parse error occurs; byte position, the last token, and an exception is passed +bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex); +``` + +The return value of each function determines whether parsing should proceed. + +To implement your own SAX handler, proceed as follows: + +1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax` as base class, but you can also use any class where the functions described above are implemented and public. +2. Create an object of your SAX interface class, e.g. `my_sax`. +3. Call `#!cpp bool json::sax_parse(input, &my_sax);` where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface. + +Note the `sax_parse` function only returns a `#!cpp bool` indicating the result of the last executed SAX event. It does not return `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file `json_sax.hpp`. + +## See also + +- [json_sax](../../api/json_sax/index.md) - documentation of the SAX interface +- [sax_parse](../../api/basic_json/sax_parse.md) - SAX parser diff --git a/features/parsing/sax_interface/index.html b/features/parsing/sax_interface/index.html index a34880448..8f6ff3b20 100644 --- a/features/parsing/sax_interface/index.html +++ b/features/parsing/sax_interface/index.html @@ -49,4 +49,4 @@ class sax_t ["json::sax_t"] { // called when a parse error occurs; byte position, the last token, and an exception is passed bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex); -

    The return value of each function determines whether parsing should proceed.

    To implement your own SAX handler, proceed as follows:

    1. Implement the SAX interface in a class. You can use class nlohmann::json_sax<json> as base class, but you can also use any class where the functions described above are implemented and public.
    2. Create an object of your SAX interface class, e.g. my_sax.
    3. Call bool json::sax_parse(input, &my_sax); where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.

    Note the sax_parse function only returns a bool indicating the result of the last executed SAX event. It does not return json value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your parse_error implementation. Internally, the SAX interface is used for the DOM parser (class json_sax_dom_parser) as well as the acceptor (json_sax_acceptor), see file json_sax.hpp.

    See also

    \ No newline at end of file +

    The return value of each function determines whether parsing should proceed.

    To implement your own SAX handler, proceed as follows:

    1. Implement the SAX interface in a class. You can use class nlohmann::json_sax<json> as base class, but you can also use any class where the functions described above are implemented and public.
    2. Create an object of your SAX interface class, e.g. my_sax.
    3. Call bool json::sax_parse(input, &my_sax); where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface.

    Note the sax_parse function only returns a bool indicating the result of the last executed SAX event. It does not return json value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your parse_error implementation. Internally, the SAX interface is used for the DOM parser (class json_sax_dom_parser) as well as the acceptor (json_sax_acceptor), see file json_sax.hpp.

    See also

    \ No newline at end of file diff --git a/features/parsing/sax_interface/index.md b/features/parsing/sax_interface/index.md new file mode 100644 index 000000000..62346cabb --- /dev/null +++ b/features/parsing/sax_interface/index.md @@ -0,0 +1,76 @@ +# SAX Interface + +The library uses a SAX-like interface with the following functions: + +``` +classDiagram + +class sax_t ["json::sax_t"] { + <> + +bool null()* + + +bool boolean(bool val)* + + +bool number_integer(number_integer_t val)* + +bool number_unsigned(number_unsigned_t val)* + + +bool number_float(number_float_t val, const string_t& s)* + + +bool string(string_t& val)* + +bool binary(binary_t& val)* + + +bool start_object(std::size_t elements)* + +bool end_object()* + +bool start_array(std::size_t elements)* + +bool end_array()* + +bool key(string_t& val)* + + +bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex)* +} +``` + +``` +// called when null is parsed +bool null(); + +// called when a boolean is parsed; value is passed +bool boolean(bool val); + +// called when a signed or unsigned integer number is parsed; value is passed +bool number_integer(number_integer_t val); +bool number_unsigned(number_unsigned_t val); + +// called when a floating-point number is parsed; value and original string is passed +bool number_float(number_float_t val, const string_t& s); + +// called when a string is parsed; value is passed and can be safely moved away +bool string(string_t& val); +// called when a binary value is parsed; value is passed and can be safely moved away +bool binary(binary_t& val); + +// called when an object or array begins or ends, resp. The number of elements is passed (or -1 if not known) +bool start_object(std::size_t elements); +bool end_object(); +bool start_array(std::size_t elements); +bool end_array(); +// called when an object key is parsed; value is passed and can be safely moved away +bool key(string_t& val); + +// called when a parse error occurs; byte position, the last token, and an exception is passed +bool parse_error(std::size_t position, const std::string& last_token, const json::exception& ex); +``` + +The return value of each function determines whether parsing should proceed. + +To implement your own SAX handler, proceed as follows: + +1. Implement the SAX interface in a class. You can use class `nlohmann::json_sax` as base class, but you can also use any class where the functions described above are implemented and public. +1. Create an object of your SAX interface class, e.g. `my_sax`. +1. Call `bool json::sax_parse(input, &my_sax);` where the first parameter can be any input like a string or an input stream and the second parameter is a pointer to your SAX interface. + +Note the `sax_parse` function only returns a `bool` indicating the result of the last executed SAX event. It does not return `json` value - it is up to you to decide what to do with the SAX events. Furthermore, no exceptions are thrown in case of a parse error - it is up to you what to do with the exception object passed to your `parse_error` implementation. Internally, the SAX interface is used for the DOM parser (class `json_sax_dom_parser`) as well as the acceptor (`json_sax_acceptor`), see file `json_sax.hpp`. + +## See also + +- [json_sax](https://json.nlohmann.me/api/json_sax/index.md) - documentation of the SAX interface +- [sax_parse](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) - SAX parser diff --git a/features/serialization.md b/features/serialization.md new file mode 100644 index 000000000..a875fcdde --- /dev/null +++ b/features/serialization.md @@ -0,0 +1,129 @@ +# Serialization + +Serialization is the process of turning a JSON value back into JSON text. It is the counterpart to +[parsing](parsing/index.md). The central function is [`dump`](../api/basic_json/dump.md), which returns the JSON text as +a string. + +```cpp +json j = {{"pi", 3.141}, {"happy", true}}; + +std::string s = j.dump(); // {"happy":true,"pi":3.141} +``` + +To write a value directly to a stream (for example, a file or `#!cpp std::cout`), the +[`operator<<`](../api/operator_ltlt.md) is provided: + +```cpp +std::cout << j << std::endl; +``` + +!!! note "String, not raw value" + + `dump` always returns a **JSON text**. Serializing a JSON string therefore includes the surrounding quotes and + escapes special characters. To obtain the *contained* string value without quotes, use + [`get()`](conversions.md) instead of `dump`. See the [converting values](conversions.md) page. + +## Pretty-printing + +By default, `dump` produces the most compact representation without any superfluous whitespace. Passing a non-negative +`indent` argument pretty-prints the output with the given number of spaces per level: + +??? example + + ```cpp + --8<-- "examples/dump.cpp" + ``` + + Output: + + ```json + --8<-- "examples/dump.output" + ``` + +The indentation character can be changed with the second argument (e.g., a tab `#!cpp '\t'`). An `indent` of `0` inserts +newlines but no leading spaces, and the default of `#!cpp -1` selects the compact single-line form. + +## Non-ASCII characters + +Strings are stored and serialized as UTF-8 (see [types](types/index.md#strings)). By default, `dump` copies valid +non-ASCII characters as-is. Setting the third argument `ensure_ascii` to `#!cpp true` escapes all non-ASCII characters +with `\uXXXX` sequences, so that the output contains only ASCII characters: + +```cpp +json j = "苹果"; +j.dump(); // "苹果" +j.dump(-1, ' ', true); // "苹果" +``` + +## Handling invalid UTF-8 + +If a string contains invalid UTF-8 sequences (for example, because it holds data in another encoding such as Latin-1), +serialization fails by default. The fourth argument of `dump` selects an +[`error_handler`](../api/basic_json/error_handler_t.md): + +- `strict` (default) — throw a [`type_error.316`](../home/exceptions.md#jsonexceptiontype_error316) exception. +- `replace` — replace invalid bytes with the Unicode replacement character U+FFFD (`�`). +- `ignore` — silently drop invalid bytes. + +??? example + + ```cpp + --8<-- "examples/error_handler_t.cpp" + ``` + + Output: + + ```json + --8<-- "examples/error_handler_t.output" + ``` + +!!! tip "Avoiding invalid UTF-8" + + The best fix is to ensure that all strings are UTF-8 encoded before storing them. See the + [FAQ on non-ASCII characters](../home/faq.md#parse-errors-reading-non-ascii-characters) for how to convert wide or + Latin-1 strings. + +## Numbers, NaN, and binary values + +- **Numbers** are serialized with enough precision to round-trip; see [number serialization](types/number_handling.md#number-serialization). +- **NaN and infinity** cannot be represented in JSON and are serialized as `#!json null`; see + [NaN handling](types/number_handling.md#nan-handling). The [binary formats](binary_formats/index.md) can preserve + them. +- **Binary values** have no JSON representation and are serialized as a helper object for debugging only; see + [binary values](binary_values.md#serialization). + +## Using `std::format`, `std::print`, and `fmt` + +Since version 3.12.0, JSON values can be formatted directly with C++20's +[`std::format`](https://en.cppreference.com/w/cpp/utility/format/format) whenever the standard library provides the +`` header (controlled by [`JSON_HAS_STD_FORMAT`](../api/macros/json_has_std_format.md)). This is enabled by the +[`std::formatter`](../api/basic_json/std_formatter.md) specialization, which also makes JSON values work with +`std::format_to` and with C++23's `std::print`/`std::println`: + +```cpp +std::print("{}", j); // compact, like j.dump() +std::print("{:2}", j); // pretty-printed with indent 2 (like j.dump(2)) +std::println("{:#}", j); // pretty-printed with the default indent +``` + +The format spec mirrors the `dump` parameters: `#!cpp "{:#}"` pretty-prints, a width such as `#!cpp "{:2}"` sets the +indent, and a fill-and-align prefix such as `#!cpp "{:.>#}"` sets the indent character. + +For the [{fmt}](https://github.com/fmtlib/fmt) library, the library ships a +[`format_as`](../api/basic_json/format_as.md) helper. Note its behavior depends on the `fmt` version; see the +[FAQ entry](../home/faq.md#using-json-values-with-stdformat-or-fmt) for the details and a recipe for a full +`fmt::formatter` specialization. + +## Serializing to other formats + +Besides JSON text, a value can also be serialized to the more compact [binary formats](binary_formats/index.md) +(BJData, BSON, CBOR, MessagePack, UBJSON). + +## See also + +- [`dump`](../api/basic_json/dump.md) - serialize to a JSON-formatted string +- [`operator<<`](../api/operator_ltlt.md) - serialize to a stream +- [`to_string`](../api/basic_json/to_string.md) - user-defined-conversion helper +- [`std::formatter`](../api/basic_json/std_formatter.md) - use JSON values with `std::format` and `std::print` +- [`format_as`](../api/basic_json/format_as.md) - use JSON values with the {fmt} library +- [Parsing](parsing/index.md) - the reverse operation diff --git a/features/serialization/index.html b/features/serialization/index.html index e5e85c09e..31a58a8bf 100644 --- a/features/serialization/index.html +++ b/features/serialization/index.html @@ -138,4 +138,4 @@

    Avoiding invalid UTF-8

    The best fix is to ensure that all strings are UTF-8 encoded before storing them. See the FAQ on non-ASCII characters for how to convert wide or Latin-1 strings.

    Numbers, NaN, and binary values

    • Numbers are serialized with enough precision to round-trip; see number serialization.
    • NaN and infinity cannot be represented in JSON and are serialized as null; see NaN handling. The binary formats can preserve them.
    • Binary values have no JSON representation and are serialized as a helper object for debugging only; see binary values.

    Using std::format, std::print, and fmt

    Since version 3.12.0, JSON values can be formatted directly with C++20's std::format whenever the standard library provides the <format> header (controlled by JSON_HAS_STD_FORMAT). This is enabled by the std::formatter<basic_json> specialization, which also makes JSON values work with std::format_to and with C++23's std::print/std::println:

    std::print("{}", j);      // compact, like j.dump()
     std::print("{:2}", j);    // pretty-printed with indent 2 (like j.dump(2))
     std::println("{:#}", j);  // pretty-printed with the default indent
    -

    The format spec mirrors the dump parameters: "{:#}" pretty-prints, a width such as "{:2}" sets the indent, and a fill-and-align prefix such as "{:.>#}" sets the indent character.

    For the {fmt} library, the library ships a format_as helper. Note its behavior depends on the fmt version; see the FAQ entry for the details and a recipe for a full fmt::formatter specialization.

    Serializing to other formats

    Besides JSON text, a value can also be serialized to the more compact binary formats (BJData, BSON, CBOR, MessagePack, UBJSON).

    See also

    \ No newline at end of file +

    The format spec mirrors the dump parameters: "{:#}" pretty-prints, a width such as "{:2}" sets the indent, and a fill-and-align prefix such as "{:.>#}" sets the indent character.

    For the {fmt} library, the library ships a format_as helper. Note its behavior depends on the fmt version; see the FAQ entry for the details and a recipe for a full fmt::formatter specialization.

    Serializing to other formats

    Besides JSON text, a value can also be serialized to the more compact binary formats (BJData, BSON, CBOR, MessagePack, UBJSON).

    See also

    \ No newline at end of file diff --git a/features/serialization/index.md b/features/serialization/index.md new file mode 100644 index 000000000..68b161731 --- /dev/null +++ b/features/serialization/index.md @@ -0,0 +1,230 @@ +# Serialization + +Serialization is the process of turning a JSON value back into JSON text. It is the counterpart to [parsing](https://json.nlohmann.me/features/parsing/index.md). The central function is [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md), which returns the JSON text as a string. + +``` +json j = {{"pi", 3.141}, {"happy", true}}; + +std::string s = j.dump(); // {"happy":true,"pi":3.141} +``` + +To write a value directly to a stream (for example, a file or `std::cout`), the [`operator<<`](https://json.nlohmann.me/api/operator_ltlt/index.md) is provided: + +``` +std::cout << j << std::endl; +``` + +String, not raw value + +`dump` always returns a **JSON text**. Serializing a JSON string therefore includes the surrounding quotes and escapes special characters. To obtain the *contained* string value without quotes, use [`get()`](https://json.nlohmann.me/features/conversions/index.md) instead of `dump`. See the [converting values](https://json.nlohmann.me/features/conversions/index.md) page. + +## Pretty-printing + +By default, `dump` produces the most compact representation without any superfluous whitespace. Passing a non-negative `indent` argument pretty-prints the output with the given number of spaces per level: + +Example + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + json j_string = "Hellö 😀!"; + + // call dump() + std::cout << "objects:" << '\n' + << j_object.dump() << "\n\n" + << j_object.dump(-1) << "\n\n" + << j_object.dump(0) << "\n\n" + << j_object.dump(4) << "\n\n" + << j_object.dump(1, '\t') << "\n\n"; + + std::cout << "arrays:" << '\n' + << j_array.dump() << "\n\n" + << j_array.dump(-1) << "\n\n" + << j_array.dump(0) << "\n\n" + << j_array.dump(4) << "\n\n" + << j_array.dump(1, '\t') << "\n\n"; + + std::cout << "strings:" << '\n' + << j_string.dump() << '\n' + << j_string.dump(-1, ' ', true) << '\n'; + + // create JSON value with invalid UTF-8 byte sequence + json j_invalid = "ä\xA9ü"; + try + { + std::cout << j_invalid.dump() << std::endl; + } + catch (const json::type_error& e) + { + std::cout << e.what() << std::endl; + } + + std::cout << "string with replaced invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace) + << "\nstring with ignored invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore) + << '\n'; +} +``` + +Output: + +``` +objects: +{"one":1,"two":2} + +{"one":1,"two":2} + +{ +"one": 1, +"two": 2 +} + +{ + "one": 1, + "two": 2 +} + +{ + "one": 1, + "two": 2 +} + +arrays: +[1,2,4,8,16] + +[1,2,4,8,16] + +[ +1, +2, +4, +8, +16 +] + +[ + 1, + 2, + 4, + 8, + 16 +] + +[ + 1, + 2, + 4, + 8, + 16 +] + +strings: +"Hellö 😀!" +"Hell\u00f6 \ud83d\ude00!" +[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 +string with replaced invalid characters: "ä�ü" +string with ignored invalid characters: "äü" +``` + +The indentation character can be changed with the second argument (e.g., a tab `'\t'`). An `indent` of `0` inserts newlines but no leading spaces, and the default of `-1` selects the compact single-line form. + +## Non-ASCII characters + +Strings are stored and serialized as UTF-8 (see [types](https://json.nlohmann.me/features/types/#strings)). By default, `dump` copies valid non-ASCII characters as-is. Setting the third argument `ensure_ascii` to `true` escapes all non-ASCII characters with `\uXXXX` sequences, so that the output contains only ASCII characters: + +``` +json j = "苹果"; +j.dump(); // "苹果" +j.dump(-1, ' ', true); // "苹果" +``` + +## Handling invalid UTF-8 + +If a string contains invalid UTF-8 sequences (for example, because it holds data in another encoding such as Latin-1), serialization fails by default. The fourth argument of `dump` selects an [`error_handler`](https://json.nlohmann.me/api/basic_json/error_handler_t/index.md): + +- `strict` (default) — throw a [`type_error.316`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error316) exception. +- `replace` — replace invalid bytes with the Unicode replacement character U+FFFD (`�`). +- `ignore` — silently drop invalid bytes. + +Example + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON value with invalid UTF-8 byte sequence + json j_invalid = "ä\xA9ü"; + try + { + std::cout << j_invalid.dump() << std::endl; + } + catch (const json::type_error& e) + { + std::cout << e.what() << std::endl; + } + + std::cout << "string with replaced invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::replace) + << "\nstring with ignored invalid characters: " + << j_invalid.dump(-1, ' ', false, json::error_handler_t::ignore) + << '\n'; +} +``` + +Output: + +``` +[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 +string with replaced invalid characters: "ä�ü" +string with ignored invalid characters: "äü" +``` + +Avoiding invalid UTF-8 + +The best fix is to ensure that all strings are UTF-8 encoded before storing them. See the [FAQ on non-ASCII characters](https://json.nlohmann.me/home/faq/#parse-errors-reading-non-ascii-characters) for how to convert wide or Latin-1 strings. + +## Numbers, NaN, and binary values + +- **Numbers** are serialized with enough precision to round-trip; see [number serialization](https://json.nlohmann.me/features/types/number_handling/#number-serialization). +- **NaN and infinity** cannot be represented in JSON and are serialized as `null`; see [NaN handling](https://json.nlohmann.me/features/types/number_handling/#nan-handling). The [binary formats](https://json.nlohmann.me/features/binary_formats/index.md) can preserve them. +- **Binary values** have no JSON representation and are serialized as a helper object for debugging only; see [binary values](https://json.nlohmann.me/features/binary_values/#serialization). + +## Using `std::format`, `std::print`, and `fmt` + +Since version 3.12.0, JSON values can be formatted directly with C++20's [`std::format`](https://en.cppreference.com/w/cpp/utility/format/format) whenever the standard library provides the `` header (controlled by [`JSON_HAS_STD_FORMAT`](https://json.nlohmann.me/api/macros/json_has_std_format/index.md)). This is enabled by the [`std::formatter`](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) specialization, which also makes JSON values work with `std::format_to` and with C++23's `std::print`/`std::println`: + +``` +std::print("{}", j); // compact, like j.dump() +std::print("{:2}", j); // pretty-printed with indent 2 (like j.dump(2)) +std::println("{:#}", j); // pretty-printed with the default indent +``` + +The format spec mirrors the `dump` parameters: `"{:#}"` pretty-prints, a width such as `"{:2}"` sets the indent, and a fill-and-align prefix such as `"{:.>#}"` sets the indent character. + +For the [{fmt}](https://github.com/fmtlib/fmt) library, the library ships a [`format_as`](https://json.nlohmann.me/api/basic_json/format_as/index.md) helper. Note its behavior depends on the `fmt` version; see the [FAQ entry](https://json.nlohmann.me/home/faq/#using-json-values-with-stdformat-or-fmt) for the details and a recipe for a full `fmt::formatter` specialization. + +## Serializing to other formats + +Besides JSON text, a value can also be serialized to the more compact [binary formats](https://json.nlohmann.me/features/binary_formats/index.md) (BJData, BSON, CBOR, MessagePack, UBJSON). + +## See also + +- [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) - serialize to a JSON-formatted string +- [`operator<<`](https://json.nlohmann.me/api/operator_ltlt/index.md) - serialize to a stream +- [`to_string`](https://json.nlohmann.me/api/basic_json/to_string/index.md) - user-defined-conversion helper +- [`std::formatter`](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) - use JSON values with `std::format` and `std::print` +- [`format_as`](https://json.nlohmann.me/api/basic_json/format_as/index.md) - use JSON values with the {fmt} library +- [Parsing](https://json.nlohmann.me/features/parsing/index.md) - the reverse operation diff --git a/features/trailing_commas.md b/features/trailing_commas.md new file mode 100644 index 000000000..735ece569 --- /dev/null +++ b/features/trailing_commas.md @@ -0,0 +1,39 @@ +# Trailing Commas + +Like [comments](comments.md), this library does not support trailing commas in arrays and objects *by default*. + +You can set parameter `ignore_trailing_commas` to `#!cpp true` in the [`parse`](../api/basic_json/parse.md) function to allow trailing commas in arrays and objects. Note that a single comma as the only content of the array or object (`[,]` or `{,}`) is not allowed, and multiple trailing commas (`[1,,]`) are not allowed either. + +This library does not add trailing commas when serializing JSON data. + +For more information, see [JSON With Commas and Comments (JWCC)](https://nigeltao.github.io/blog/2021/json-with-commas-comments.html). + +!!! example + + Consider the following JSON with trailing commas. + + ```json + { + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune", + ] + } + ``` + + When calling `parse` without additional argument, a parse error exception is thrown. If `ignore_trailing_commas` is set to `#!cpp true`, the trailing commas are ignored during parsing: + + ```cpp + --8<-- "examples/trailing_commas.cpp" + ``` + + Output: + + ``` + --8<-- "examples/trailing_commas.output" + ``` diff --git a/features/trailing_commas/index.html b/features/trailing_commas/index.html index 1202dbcfb..3d51d6138 100644 --- a/features/trailing_commas/index.html +++ b/features/trailing_commas/index.html @@ -58,4 +58,4 @@ "Neptune" ] } -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/features/trailing_commas/index.md b/features/trailing_commas/index.md new file mode 100644 index 000000000..a9355fbe2 --- /dev/null +++ b/features/trailing_commas/index.md @@ -0,0 +1,86 @@ +# Trailing Commas + +Like [comments](https://json.nlohmann.me/features/comments/index.md), this library does not support trailing commas in arrays and objects *by default*. + +You can set parameter `ignore_trailing_commas` to `true` in the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function to allow trailing commas in arrays and objects. Note that a single comma as the only content of the array or object (`[,]` or `{,}`) is not allowed, and multiple trailing commas (`[1,,]`) are not allowed either. + +This library does not add trailing commas when serializing JSON data. + +For more information, see [JSON With Commas and Comments (JWCC)](https://nigeltao.github.io/blog/2021/json-with-commas-comments.html). + +Example + +Consider the following JSON with trailing commas. + +``` +{ + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune", + ] +} +``` + +When calling `parse` without additional argument, a parse error exception is thrown. If `ignore_trailing_commas` is set to `true`, the trailing commas are ignored during parsing: + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::string s = R"( + { + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune", + ] + } + )"; + + try + { + json j = json::parse(s); + } + catch (json::exception& e) + { + std::cout << e.what() << std::endl; + } + + json j = json::parse(s, + /* callback */ nullptr, + /* allow exceptions */ true, + /* ignore_comments */ false, + /* ignore_trailing_commas */ true); + std::cout << j.dump(2) << '\n'; +} +``` + +Output: + +``` +[json.exception.parse_error.101] parse error at line 11, column 9: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal +{ + "planets": [ + "Mercury", + "Venus", + "Earth", + "Mars", + "Jupiter", + "Uranus", + "Neptune" + ] +} +``` diff --git a/features/types.md b/features/types.md new file mode 100644 index 000000000..78e332936 --- /dev/null +++ b/features/types.md @@ -0,0 +1,271 @@ +# Types + +This page gives an overview of how JSON values are stored and how this can be configured. + +## Overview + +By default, JSON values are stored as follows: + +| JSON type | C++ type | +|-----------|-----------------------------------------------| +| object | `std::map` | +| array | `std::vector` | +| null | `std::nullptr_t` | +| string | `std::string` | +| boolean | `bool` | +| number | `std::int64_t`, `std::uint64_t`, and `double` | + +Note there are three different types for numbers - when parsing JSON text, the best fitting type is chosen. + +## Storage + +```mermaid +classDiagram + +class value_t { + <> + null + object + array + string + boolean + number_integer + number_unsigned + number_float + binary + discarded +} + +class json_value { + <> + object_t* object + array_t* array + string_t* string + binary_t* binary + boolean_t boolean + number_integer_t number_integer + number_unsigned_t number_unsigned + number_float_t number_float +} + +class basic_json { + -value_t m_type + -json_value m_value + +typedef object_t + +typedef array_t + +typedef binary_t + +typedef boolean_t + +typedef number_integer_t + +typedef number_unsigned_t + +typedef number_float_t +} + +basic_json .. json_value +basic_json .. value_t +``` + +## Template arguments + +The data types to store a JSON value are derived from the template arguments passed to class `basic_json`: + +```cpp +template< + template class ObjectType = std::map, + template class ArrayType = std::vector, + class StringType = std::string, + class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = adl_serializer, + class BinaryType = std::vector +> +class basic_json; +``` + +Type `json` is an alias for `basic_json<>` and uses the default types. + +From the template arguments, the following types are derived: + +```cpp +using object_comparator_t = std::less<>; +using object_t = ObjectType>>; + +using array_t = ArrayType>; + +using string_t = StringType; + +using boolean_t = BooleanType; + +using number_integer_t = NumberIntegerType; +using number_unsigned_t = NumberUnsignedType; +using number_float_t = NumberFloatType; + +using binary_t = nlohmann::byte_container_with_subtype; +``` + + +## Objects + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: + +> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array. + +### Default type + +With the default values for *ObjectType* (`std::map`), *StringType* (`std::string`), and *AllocatorType* (`std::allocator`), the default value for `object_t` is: + +```cpp +std::map< + std::string, // key_type + basic_json, // value_type + std::less<>, // key_compare + std::allocator> // allocator_type +> +``` + +### Behavior + +The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following behavior: + +- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings. +- When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, `#!json {"key": 2, "key": 1}` could be equal to either `#!json {"key": 1}` or `#!json {"key": 2}`. +- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see `dump`) in this order. For instance, both `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be stored and serialized as `#!json {"a": 2, "b": 1}`. +- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, `#!json {"b": 1, "a": 2}` and `#!json {"a": 2, "b": 1}` will be treated as equal. + +### Key order + +The order in which name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON objects. + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON object. + +### Storage + +Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type `object_t*` must be dereferenced. + + +## Arrays + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: + +> An array is an ordered sequence of zero or more values. + +### Default type + +With the default values for *ArrayType* (`std::vector`) and *AllocatorType* (`std::allocator`), the default value for `array_t` is: + +```cpp +std::vector< + basic_json, // value_type + std::allocator // allocator_type +> +``` + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON array. + +### Storage + +Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type `array_t*` must be dereferenced. + + +## Strings + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: + +> A string is a sequence of zero or more Unicode characters. + +Unicode values are split by the JSON class into byte-sized characters during deserialization. + +### Default type + +With the default values for *StringType* (`std::string`), the default value for `string_t` is `#!cpp std::string`. + +### Encoding + +Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return the number of **bytes** in the string rather than the number of characters or glyphs. + +### String comparison + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal. + +This implementation is interoperable as it does compare strings code unit by code unit. + +### Storage + +String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type `string_t*` must be dereferenced. + + +## Booleans + +[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`. + +### Default type + +With the default values for *BooleanType* (`#!cpp bool`), the default value for `boolean_t` is `#!cpp bool`. + +### Storage + +Boolean values are stored directly inside a `basic_json` type. + +## Numbers + +See the [number handling](number_handling.md) article for a detailed discussion on how numbers are handled by this library. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: + +> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, `number_integer_t`, `number_unsigned_t`, and `number_float_t` are used. + +### Default types + +With the default values for *NumberIntegerType* (`std::int64_t`), the default value for `number_integer_t` is `std::int64_t`. +With the default values for *NumberUnsignedType* (`std::uint64_t`), the default value for `number_unsigned_t` is `std::uint64_t`. +With the default values for *NumberFloatType* (`#!cpp double`), the default value for `number_float_t` is `#!cpp double`. + +### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ integer literal `#!c 010` will be serialized to `#!c 8`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `#!json null`. + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `#!c 9223372036854775807` (`INT64_MAX`) and the minimal integer number that can be stored is `#!c -9223372036854775808` (`INT64_MIN`). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as `number_unsigned_t` or `number_float_t`. + +When the default type is used, the maximal unsigned integer number that can be stored is `#!c 18446744073709551615` (`UINT64_MAX`) and the minimal integer number that can be stored is `#!c 0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as `number_integer_t` or `number_float_t`. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: + +> Note that when such software is used, numbers that are integers and are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange of the exactly supported range [`INT64_MIN`, `INT64_MAX`], this class's integer type is interoperable. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. + +This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than `#!c -1.79769313486232e+308` and values greater than `#!c 1.79769313486232e+308` will be stored as NaN internally and be serialized to `#!json null`. + +### Storage + +Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a `basic_json` type. diff --git a/features/types/index.html b/features/types/index.html index a733c16e2..3bdcf3077 100644 --- a/features/types/index.html +++ b/features/types/index.html @@ -77,4 +77,4 @@ basic_json .. value_t

    Template arguments< basic_json, // value_type std::allocator<basic_json> // allocator_type > -

    Limits

    RFC 8259 specifies:

    An implementation may set limits on the maximum depth of nesting.

    In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON array.

    Storage

    Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of type array_t* must be dereferenced.

    Strings

    RFC 8259 describes JSON strings as follows:

    A string is a sequence of zero or more Unicode characters.

    Unicode values are split by the JSON class into byte-sized characters during deserialization.

    Default type

    With the default values for StringType (std::string), the default value for string_t is std::string.

    Encoding

    Strings are stored in UTF-8 encoding. Therefore, functions like std::string::size() or std::string::length() return the number of bytes in the string rather than the number of characters or glyphs.

    String comparison

    RFC 8259 states:

    Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that "a\\b" and "a\u005Cb" are not equal.

    This implementation is interoperable as it does compare strings code unit by code unit.

    Storage

    String values are stored as pointers in a basic_json type. That is, for any access to string values, a pointer of type string_t* must be dereferenced.

    Booleans

    RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false.

    Default type

    With the default values for BooleanType (bool), the default value for boolean_t is bool.

    Storage

    Boolean values are stored directly inside a basic_json type.

    Numbers

    See the number handling article for a detailed discussion on how numbers are handled by this library.

    RFC 8259 describes numbers as follows:

    The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

    This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t, and number_float_t are used.

    Default types

    With the default values for NumberIntegerType (std::int64_t), the default value for number_integer_t is std::int64_t. With the default values for NumberUnsignedType (std::uint64_t), the default value for number_unsigned_t is std::uint64_t. With the default values for NumberFloatType (double), the default value for number_float_t is double.

    Default behavior

    • The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ integer literal 010 will be serialized to 8. During deserialization, leading zeros yield an error.
    • Not-a-number (NaN) values will be serialized to null.

    Limits

    RFC 8259 specifies:

    An implementation may set limits on the range and precision of numbers.

    When the default type is used, the maximal integer number that can be stored is 9223372036854775807 (INT64_MAX) and the minimal integer number that can be stored is -9223372036854775808 (INT64_MIN). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_unsigned_t or number_float_t.

    When the default type is used, the maximal unsigned integer number that can be stored is 18446744073709551615 (UINT64_MAX) and the minimal integer number that can be stored is 0. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_integer_t or number_float_t.

    RFC 8259 further states:

    Note that when such software is used, numbers that are integers and are in the range [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

    As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is interoperable.

    RFC 8259 states:

    This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.

    This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than -1.79769313486232e+308 and values greater than 1.79769313486232e+308 will be stored as NaN internally and be serialized to null.

    Storage

    Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a basic_json type.

    \ No newline at end of file +

    Limits

    RFC 8259 specifies:

    An implementation may set limits on the maximum depth of nesting.

    In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the max_size function of a JSON array.

    Storage

    Arrays are stored as pointers in a basic_json type. That is, for any access to array values, a pointer of type array_t* must be dereferenced.

    Strings

    RFC 8259 describes JSON strings as follows:

    A string is a sequence of zero or more Unicode characters.

    Unicode values are split by the JSON class into byte-sized characters during deserialization.

    Default type

    With the default values for StringType (std::string), the default value for string_t is std::string.

    Encoding

    Strings are stored in UTF-8 encoding. Therefore, functions like std::string::size() or std::string::length() return the number of bytes in the string rather than the number of characters or glyphs.

    String comparison

    RFC 8259 states:

    Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that "a\\b" and "a\u005Cb" are not equal.

    This implementation is interoperable as it does compare strings code unit by code unit.

    Storage

    String values are stored as pointers in a basic_json type. That is, for any access to string values, a pointer of type string_t* must be dereferenced.

    Booleans

    RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false.

    Default type

    With the default values for BooleanType (bool), the default value for boolean_t is bool.

    Storage

    Boolean values are stored directly inside a basic_json type.

    Numbers

    See the number handling article for a detailed discussion on how numbers are handled by this library.

    RFC 8259 describes numbers as follows:

    The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

    This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, number_integer_t, number_unsigned_t, and number_float_t are used.

    Default types

    With the default values for NumberIntegerType (std::int64_t), the default value for number_integer_t is std::int64_t. With the default values for NumberUnsignedType (std::uint64_t), the default value for number_unsigned_t is std::uint64_t. With the default values for NumberFloatType (double), the default value for number_float_t is double.

    Default behavior

    • The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ integer literal 010 will be serialized to 8. During deserialization, leading zeros yield an error.
    • Not-a-number (NaN) values will be serialized to null.

    Limits

    RFC 8259 specifies:

    An implementation may set limits on the range and precision of numbers.

    When the default type is used, the maximal integer number that can be stored is 9223372036854775807 (INT64_MAX) and the minimal integer number that can be stored is -9223372036854775808 (INT64_MIN). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_unsigned_t or number_float_t.

    When the default type is used, the maximal unsigned integer number that can be stored is 18446744073709551615 (UINT64_MAX) and the minimal integer number that can be stored is 0. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as number_integer_t or number_float_t.

    RFC 8259 further states:

    Note that when such software is used, numbers that are integers and are in the range [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values.

    As this range is a subrange of the exactly supported range [INT64_MIN, INT64_MAX], this class's integer type is interoperable.

    RFC 8259 states:

    This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision.

    This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than -1.79769313486232e+308 and values greater than 1.79769313486232e+308 will be stored as NaN internally and be serialized to null.

    Storage

    Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a basic_json type.

    \ No newline at end of file diff --git a/features/types/index.md b/features/types/index.md new file mode 100644 index 000000000..71427889e --- /dev/null +++ b/features/types/index.md @@ -0,0 +1,265 @@ +# Types + +This page gives an overview of how JSON values are stored and how this can be configured. + +## Overview + +By default, JSON values are stored as follows: + +| JSON type | C++ type | +| --------- | --------------------------------------------- | +| object | `std::map` | +| array | `std::vector` | +| null | `std::nullptr_t` | +| string | `std::string` | +| boolean | `bool` | +| number | `std::int64_t`, `std::uint64_t`, and `double` | + +Note there are three different types for numbers - when parsing JSON text, the best fitting type is chosen. + +## Storage + +``` +classDiagram + +class value_t { + <> + null + object + array + string + boolean + number_integer + number_unsigned + number_float + binary + discarded +} + +class json_value { + <> + object_t* object + array_t* array + string_t* string + binary_t* binary + boolean_t boolean + number_integer_t number_integer + number_unsigned_t number_unsigned + number_float_t number_float +} + +class basic_json { + -value_t m_type + -json_value m_value + +typedef object_t + +typedef array_t + +typedef binary_t + +typedef boolean_t + +typedef number_integer_t + +typedef number_unsigned_t + +typedef number_float_t +} + +basic_json .. json_value +basic_json .. value_t +``` + +## Template arguments + +The data types to store a JSON value are derived from the template arguments passed to class `basic_json`: + +``` +template< + template class ObjectType = std::map, + template class ArrayType = std::vector, + class StringType = std::string, + class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = adl_serializer, + class BinaryType = std::vector +> +class basic_json; +``` + +Type `json` is an alias for `basic_json<>` and uses the default types. + +From the template arguments, the following types are derived: + +``` +using object_comparator_t = std::less<>; +using object_t = ObjectType>>; + +using array_t = ArrayType>; + +using string_t = StringType; + +using boolean_t = BooleanType; + +using number_integer_t = NumberIntegerType; +using number_unsigned_t = NumberUnsignedType; +using number_float_t = NumberFloatType; + +using binary_t = nlohmann::byte_container_with_subtype; +``` + +## Objects + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: + +> An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array. + +### Default type + +With the default values for *ObjectType* (`std::map`), *StringType* (`std::string`), and *AllocatorType* (`std::allocator`), the default value for `object_t` is: + +``` +std::map< + std::string, // key_type + basic_json, // value_type + std::less<>, // key_compare + std::allocator> // allocator_type +> +``` + +### Behavior + +The choice of `object_t` influences the behavior of the JSON class. With the default type, objects have the following behavior: + +- When all names are unique, objects will be interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings. +- When the names within an object are not unique, it is unspecified which one of the values for a given key will be chosen. For instance, `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or `{"key": 2}`. +- Internally, name/value pairs are stored in lexicographical order of the names. Objects will also be serialized (see `dump`) in this order. For instance, both `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored and serialized as `{"a": 2, "b": 1}`. +- When comparing objects, the order of the name/value pairs is irrelevant. This makes objects interoperable in the sense that they will not be affected by these differences. For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be treated as equal. + +### Key order + +The order in which name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to [RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON objects. + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the object's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON object. + +### Storage + +Objects are stored as pointers in a `basic_json` type. That is, for any access to object values, a pointer of type `object_t*` must be dereferenced. + +## Arrays + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: + +> An array is an ordered sequence of zero or more values. + +### Default type + +With the default values for *ArrayType* (`std::vector`) and *AllocatorType* (`std::allocator`), the default value for `array_t` is: + +``` +std::vector< + basic_json, // value_type + std::allocator // allocator_type +> +``` + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the maximum depth of nesting. + +In this class, the array's limit of nesting is not explicitly constrained. However, a maximum depth of nesting may be introduced by the compiler or runtime environment. A theoretical limit can be queried by calling the `max_size` function of a JSON array. + +### Storage + +Arrays are stored as pointers in a `basic_json` type. That is, for any access to array values, a pointer of type `array_t*` must be dereferenced. + +## Strings + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: + +> A string is a sequence of zero or more Unicode characters. + +Unicode values are split by the JSON class into byte-sized characters during deserialization. + +### Default type + +With the default values for *StringType* (`std::string`), the default value for `string_t` is `std::string`. + +### Encoding + +Strings are stored in UTF-8 encoding. Therefore, functions like `std::string::size()` or `std::string::length()` return the number of **bytes** in the string rather than the number of characters or glyphs. + +### String comparison + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> Software implementations are typically required to test names of object members for equality. Implementations that transform the textual representation into sequences of Unicode code units and then perform the comparison numerically, code unit by code unit are interoperable in the sense that implementations will agree in all cases on equality or inequality of two strings. For example, implementations that compare strings with escaped characters unconverted may incorrectly find that `"a\\b"` and `"a\u005Cb"` are not equal. + +This implementation is interoperable as it does compare strings code unit by code unit. + +### Storage + +String values are stored as pointers in a `basic_json` type. That is, for any access to string values, a pointer of type `string_t*` must be dereferenced. + +## Booleans + +[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals `true` and `false`. + +### Default type + +With the default values for *BooleanType* (`bool`), the default value for `boolean_t` is `bool`. + +### Storage + +Boolean values are stored directly inside a `basic_json` type. + +## Numbers + +See the [number handling](https://json.nlohmann.me/features/types/number_handling/index.md) article for a detailed discussion on how numbers are handled by this library. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: + +> The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. (...) Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +This description includes both integer and floating-point numbers. However, C++ allows more precise storage if it is known whether the number is a signed integer, an unsigned integer, or a floating-point number. Therefore, three different types, `number_integer_t`, `number_unsigned_t`, and `number_float_t` are used. + +### Default types + +With the default values for *NumberIntegerType* (`std::int64_t`), the default value for `number_integer_t` is `std::int64_t`. With the default values for *NumberUnsignedType* (`std::uint64_t`), the default value for `number_unsigned_t` is `std::uint64_t`. With the default values for *NumberFloatType* (`double`), the default value for `number_float_t` is `double`. + +### Default behavior + +- The restrictions about leading zeros are not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as an octal number. Internally, the value will be stored as a decimal number. For instance, the C++ integer literal `010` will be serialized to `8`. During deserialization, leading zeros yield an error. +- Not-a-number (NaN) values will be serialized to `null`. + +### Limits + +[RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: + +> An implementation may set limits on the range and precision of numbers. + +When the default type is used, the maximal integer number that can be stored is `9223372036854775807` (`INT64_MAX`) and the minimal integer number that can be stored is `-9223372036854775808` (`INT64_MIN`). Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as `number_unsigned_t` or `number_float_t`. + +When the default type is used, the maximal unsigned integer number that can be stored is `18446744073709551615` (`UINT64_MAX`) and the minimal integer number that can be stored is `0`. Integer numbers that are out of range will yield over/underflow when used in a constructor. During deserialization, too large or small integer numbers will automatically be stored as `number_integer_t` or `number_float_t`. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) further states: + +> Note that when such software is used, numbers that are integers and are in the range [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values. + +As this range is a subrange of the exactly supported range \[`INT64_MIN`, `INT64_MAX`\], this class's integer type is interoperable. + +[RFC 8259](https://tools.ietf.org/html/rfc8259) states: + +> This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754-2008 binary64 (double precision) numbers is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. + +This implementation does exactly follow this approach, as it uses double precision floating-point numbers. Note values smaller than `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` will be stored as NaN internally and be serialized to `null`. + +### Storage + +Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a `basic_json` type. diff --git a/features/types/number_handling.md b/features/types/number_handling.md new file mode 100644 index 000000000..7fa31fb97 --- /dev/null +++ b/features/types/number_handling.md @@ -0,0 +1,341 @@ +# Number Handling + +This document describes how the library is handling numbers. + +## Background + +This section briefly summarizes how the JSON specification describes how numbers should be handled. + +### JSON number syntax + +JSON defines the syntax of numbers as follows: + +!!! quote "[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6" + + The representation of numbers is similar to that used in most + programming languages. A number is represented in base 10 using + decimal digits. It contains an integer component that may be + prefixed with an optional minus sign, which may be followed by a + fraction part and/or an exponent part. Leading zeros are not + allowed. + + A fraction part is a decimal point followed by one or more digits. + + An exponent part begins with the letter E in uppercase or lowercase, + which may be followed by a plus or minus sign. The E and optional + sign are followed by one or more digits. + +The following railroad diagram from [json.org](https://json.org) visualizes the number syntax: + +![Syntax for JSON numbers](../../images/json_syntax_number.png) + +### Number interoperability + +On number interoperability, the following remarks are made: + +!!! quote "[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6" + + This specification allows implementations to set limits on the range + and precision of numbers accepted. Since software that implements + IEEE 754 binary64 (double precision) numbers [IEEE754] is generally + available and widely used, good interoperability can be achieved by + implementations that expect no more precision or range than these + provide, in the sense that implementations will approximate JSON + numbers within the expected precision. A JSON number such as 1E400 + or 3.141592653589793238462643383279 may indicate potential + interoperability problems, since it suggests that the software that + created it expects receiving software to have greater capabilities + for numeric magnitude and precision than is widely available. + + Note that when such software is used, numbers that are integers and + are in the range $[-2^{53}+1, 2^{53}-1]$ are interoperable in the + sense that implementations will agree exactly on their numeric + values. + +## Library implementation + +This section describes how this library implements the above number specification. + +### Number storage + +In the default [`json`](../../api/json.md) type, numbers are stored as `#!c std::uint64_t`, `#!c std::int64_t`, and +`#!c double`, respectively. Thereby, `#!c std::uint64_t` and `#!c std::int64_t` are used only if they can store the +number without loss of precision. If this is impossible (e.g., if the number is too large), the number is stored as +`#!c double`. + +!!! info "Notes" + + - Numbers with a decimal digit or scientific notation are always stored as `#!c double`. + - The number types can be changed, see [Template number types](#template-number-types). + - As of version 3.9.1, the conversion is realized by + [`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul), + [`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and + [`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof), respectively. + +!!! example "Examples" + + - Integer `#!c -12345678912345789123456789` is smaller than `#!c INT64_MIN` and will be stored as floating-point + number `#!c -1.2345678912345788e+25`. + - Integer `#!c 1E3` will be stored as floating-point number `#!c 1000.0`. + +### Number limits + +- Any 64-bit signed or unsigned integer can be stored without loss of precision. +- Numbers exceeding the limits of `#!c double` (i.e., numbers that after conversion via +[`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof) are not satisfying +[`std::isfinite`](https://en.cppreference.com/w/cpp/numeric/math/isfinite) such as `#!c 1E400`) will throw exception +[`json.exception.out_of_range.406`](../../home/exceptions.md#jsonexceptionout_of_range406) during parsing. +- Floating-point numbers are rounded to the next number representable as `double`. For instance +`#!c 3.141592653589793238462643383279` is stored as [`0x400921fb54442d18`](https://float.exposed/0x400921fb54442d18). +This is the same behavior as the code `#!c double x = 3.141592653589793238462643383279;`. + +!!! success "Interoperability" + + - The library is interoperable with respect to the specification, because its supported range $[-2^{63}, 2^{64}-1]$ is + larger than the described range $[-2^{53}+1, 2^{53}-1]$. + - All integers outside the range $[-2^{63}, 2^{64}-1]$, as well as floating-point numbers are stored as `double`. + This also concurs with the specification above. + +### Zeros + +The JSON number grammar allows for different ways to express zero, and this library will store zeros differently: + +| Literal | Stored value and type | Serialization | +|---------|------------------------|---------------| +| `0` | `#!c std::uint64_t(0)` | `0` | +| `-0` | `#!c std::int64_t(0)` | `0` | +| `0.0` | `#!c double(0.0)` | `0.0` | +| `-0.0` | `#!c double(-0.0)` | `-0.0` | +| `0E0` | `#!c double(0.0)` | `0.0` | +| `-0E0` | `#!c double(-0.0)` | `-0.0` | + +That is, `-0` is stored as a signed integer, but the serialization does not reproduce the `-`. + +### Number serialization + +- Integer numbers are serialized as is; that is, no scientific notation is used. +- Floating-point numbers are serialized as specified by the `#!c %g` printf modifier with + [`std::numeric_limits::max_digits10`](https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10) + significant digits. The rationale is to use the shortest representation while still allowing round-tripping. + +!!! hint "Notes regarding precision of floating-point numbers" + + As described above, floating-point numbers are rounded to the nearest double and serialized with the shortest + representation to allow round-tripping. This can yield confusing examples: + + - The serialization can have fewer decimal places than the input: `#!c 2555.5599999999999` will be serialized as + `#!c 2555.56`. The reverse can also be true. + - The serialization can be in scientific notation even if the input is not: `#!c 0.0000972439793401814` will be + serialized as `#!c 9.72439793401814e-05`. The reverse can also be true: `#!c 12345E-5` will be serialized as + `#!c 0.12345`. + - Conversions from `#!c float` to `#!c double` can also introduce rounding errors: + ```cpp + float f = 0.3; + json j = f; + std::cout << j << '\n'; + ``` + yields `#!c 0.30000001192092896`. + + All examples here can be reproduced by passing the original double value to + + ```cpp + std::printf("%.*g\n", std::numeric_limits::max_digits10, double_value); + ``` + +#### NaN handling + +NaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded: + +!!! quote "[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6" + + Numeric values that cannot be represented in the grammar below (such + as Infinity and NaN) are not permitted. + +That is, there is no way to *parse* a NaN value. However, assignments can store NaN values in a JSON value. + +This library serializes NaN values as `#!js null`. This corresponds to the behavior of JavaScript's +[`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) function. + +!!! example + + The following example shows how a NaN value is stored in a `json` value. + + ```cpp + int main() + { + double val = std::numeric_limits::quiet_NaN(); + std::cout << "val=" << val << std::endl; + json j = val; + std::cout << "j=" << j.dump() << std::endl; + val = j; + std::cout << "val=" << val << std::endl; + } + ``` + + output: + + ``` + val=nan + j=null + val=nan + ``` + +### Number comparison + +Floating-point numbers inside JSON values are compared with `#!c json::number_float_t::operator==` which is +`#!c double::operator==` by default. + +!!! example "Alternative comparison functions" + + To compare floating-point while respecting an epsilon, an alternative + [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) + could be used, for instance + + ```cpp + template::value, T>::type> + inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept + { + return std::abs(a - b) <= epsilon; + } + ``` + Or you can self-define an operator equal function like this: + + ```cpp + bool my_equal(const_reference lhs, const_reference rhs) + { + const auto lhs_type = lhs.type(); + const auto rhs_type = rhs.type(); + if (lhs_type == rhs_type) + { + switch(lhs_type) + { + // self_defined case + case value_t::number_float: + return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); + + // other cases remain the same with the original + ... + } + } + ... + } + ``` + + (see [#703](https://github.com/nlohmann/json/issues/703) for more information.) + +!!! note + + NaN values never compare equal to themselves or to other NaN values. See [#514](https://github.com/nlohmann/json/issues/514). + +### Number conversion + +Just like the C++ language itself, the `get` family of functions allows conversions between unsigned and signed +integers, and between integers and floating-point values. This behavior may be surprising. + +!!! warning "Unconditional number conversions" + + ```cpp hl_lines="3" + double d = 42.3; // non-integer double value 42.3 + json jd = d; // stores double value 42.3 + std::int64_t i = jd.get(); // now i==42; no warning or error is produced + ``` + + Note the last line with throw a [`json.exception.type_error.302`](../../home/exceptions.md#jsonexceptiontype_error302) + exception if `jd` is not a numerical type, for instance a string. + + Numeric conversions are performed according to the corresponding C++ conversion rules. The library does not perform + range checks when converting between numeric types. + + In particular, conversions from floating-point values to integer types, or conversions to integer types with a + smaller range than the stored value, may produce implementation-defined or undefined behavior if the source value + cannot be represented by the target type. + + Applications requiring checked conversions should inspect the stored number type with + [`is_number_float()`](../../api/basic_json/is_number_float.md), + [`is_number_integer()`](../../api/basic_json/is_number_integer.md), + [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md), or + [`type()`](../../api/basic_json/type.md), and perform explicit range checks before converting to a narrower type. + +The rationale is twofold: + +1. JSON does not define a number type or precision (see above). +2. C++ also allows silently converting between number types. + +!!! success "Conditional number conversion" + + The code above can be solved by explicitly checking the nature of the value with members such as + [`is_number_integer()`](../../api/basic_json/is_number_integer.md) or + [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md): + + ```cpp hl_lines="2" + // check if jd is really integer-valued + if (jd.is_number_integer()) + { + // if so, do the conversion and use i + std::int64_t i = jd.get(); + // ... + } + else + { + // otherwise, take appropriate action + // ... + } + ``` + + Note this approach also has the advantage that it can react on non-numerical JSON value types such as strings. + + (Example taken from [#777](https://github.com/nlohmann/json/issues/777#issuecomment-459968458).) + +### Determine number types + +As the example in [Number conversion](#number-conversion) shows, there are different functions to determine the type of +the stored number: + +- [`is_number()`](../../api/basic_json/is_number.md) returns `#!c true` for any number type +- [`is_number_integer()`](../../api/basic_json/is_number_integer.md) returns `#!c true` for signed and unsigned integers +- [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md) returns `#!c true` for unsigned integers only +- [`is_number_float()`](../../api/basic_json/is_number_float.md) returns `#!c true` for floating-point numbers +- [`type_name()`](../../api/basic_json/type_name.md) returns `#!c "number"` for any number type +- [`type()`](../../api/basic_json/type.md) returns a different enumerator of + [`value_t`](../../api/basic_json/value_t.md) for all number types + +| function | unsigned integer | signed integer | floating-point | string | +|----------------------------------------------------------------------|-------------------|------------------|----------------|----------------| +| [`is_number()`](../../api/basic_json/is_number.md) | `#!c true` | `#!c true` | `#!c true` | `#!c false` | +| [`is_number_integer()`](../../api/basic_json/is_number_integer.md) | `#!c true` | `#!c true` | `#!c false` | `#!c false` | +| [`is_number_unsigned()`](../../api/basic_json/is_number_unsigned.md) | `#!c true` | `#!c false` | `#!c false` | `#!c false` | +| [`is_number_float()`](../../api/basic_json/is_number_float.md) | `#!c false` | `#!c false` | `#!c true` | `#!c false` | +| [`type_name()`](../../api/basic_json/type_name.md) | `#!c "number"` | `#!c "number"` | `#!c "number"` | `#!c "string"` | +| [`type()`](../../api/basic_json/type.md) | `number_unsigned` | `number_integer` | `number_float` | `string` | + +### Template number types + +The number types can be changed with template parameters. + +| position | number type | default type | possible values | +|----------|-------------------|---------------------|------------------------------------------------| +| 5 | signed integers | `#!c std::int64_t` | `#!c std::int32_t`, `#!c std::int16_t`, etc. | +| 6 | unsigned integers | `#!c std::uint64_t` | `#!c std::uint32_t`, `#!c std::uint16_t`, etc. | +| 7 | floating-point | `#!c double` | `#!c float`, `#!c long double` | + +!!! info "Constraints on number types" + + - The type for signed integers must be convertible from `#!c long long`. The type for floating-point numbers is used + in case of overflow. + - The type for unsigned integers must be convertible from `#!c unsigned long long`. The type for floating-point + numbers is used in case of overflow. + - The types for signed and unsigned integers must be distinct, see + [#2573](https://github.com/nlohmann/json/issues/2573). + - Only `#!c double`, `#!c float`, and `#!c long double` are supported for floating-point numbers. + +!!! example + + A `basic_json` type that uses `#!c long double` as floating-point type. + + ```cpp hl_lines="2" + using json_ld = nlohmann::basic_json; + ``` + + Note values should then be parsed with `json_ld::parse` rather than `json::parse` as the latter would parse + floating-point values to `#!c double` before then converting them to `#!c long double`. diff --git a/features/types/number_handling/index.html b/features/types/number_handling/index.html index ce70bdae3..0b6905f1a 100644 --- a/features/types/number_handling/index.html +++ b/features/types/number_handling/index.html @@ -54,4 +54,4 @@ val=nan }

    Note this approach also has the advantage that it can react on non-numerical JSON value types such as strings.

    (Example taken from #777.)

    Determine number types

    As the example in Number conversion shows, there are different functions to determine the type of the stored number:

    function unsigned integer signed integer floating-point string
    is_number() true true true false
    is_number_integer() true true false false
    is_number_unsigned() true false false false
    is_number_float() false false true false
    type_name() "number" "number" "number" "string"
    type() number_unsigned number_integer number_float string

    Template number types

    The number types can be changed with template parameters.

    position number type default type possible values
    5 signed integers std::int64_t std::int32_t, std::int16_t, etc.
    6 unsigned integers std::uint64_t std::uint32_t, std::uint16_t, etc.
    7 floating-point double float, long double

    Constraints on number types

    • The type for signed integers must be convertible from long long. The type for floating-point numbers is used in case of overflow.
    • The type for unsigned integers must be convertible from unsigned long long. The type for floating-point numbers is used in case of overflow.
    • The types for signed and unsigned integers must be distinct, see #2573.
    • Only double, float, and long double are supported for floating-point numbers.

    Example

    A basic_json type that uses long double as floating-point type.

    using json_ld = nlohmann::basic_json<std::map, std::vector, std::string, bool,
                                          std::int64_t, std::uint64_t, long double>;
    -

    Note values should then be parsed with json_ld::parse rather than json::parse as the latter would parse floating-point values to double before then converting them to long double.

    \ No newline at end of file +

    Note values should then be parsed with json_ld::parse rather than json::parse as the latter would parse floating-point values to double before then converting them to long double.

    \ No newline at end of file diff --git a/features/types/number_handling/index.md b/features/types/number_handling/index.md new file mode 100644 index 000000000..47b5f50c8 --- /dev/null +++ b/features/types/number_handling/index.md @@ -0,0 +1,282 @@ +# Number Handling + +This document describes how the library is handling numbers. + +## Background + +This section briefly summarizes how the JSON specification describes how numbers should be handled. + +### JSON number syntax + +JSON defines the syntax of numbers as follows: + +[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6 + +The representation of numbers is similar to that used in most programming languages. A number is represented in base 10 using decimal digits. It contains an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part. Leading zeros are not allowed. + +A fraction part is a decimal point followed by one or more digits. + +An exponent part begins with the letter E in uppercase or lowercase, which may be followed by a plus or minus sign. The E and optional sign are followed by one or more digits. + +The following railroad diagram from [json.org](https://json.org) visualizes the number syntax: + +### Number interoperability + +On number interoperability, the following remarks are made: + +[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6 + +This specification allows implementations to set limits on the range and precision of numbers accepted. Since software that implements IEEE 754 binary64 (double precision) numbers [IEEE754] is generally available and widely used, good interoperability can be achieved by implementations that expect no more precision or range than these provide, in the sense that implementations will approximate JSON numbers within the expected precision. A JSON number such as 1E400 or 3.141592653589793238462643383279 may indicate potential interoperability problems, since it suggests that the software that created it expects receiving software to have greater capabilities for numeric magnitude and precision than is widely available. + +Note that when such software is used, numbers that are integers and are in the range [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values. + +## Library implementation + +This section describes how this library implements the above number specification. + +### Number storage + +In the default [`json`](https://json.nlohmann.me/api/json/index.md) type, numbers are stored as `std::uint64_t`, `std::int64_t`, and `double`, respectively. Thereby, `std::uint64_t` and `std::int64_t` are used only if they can store the number without loss of precision. If this is impossible (e.g., if the number is too large), the number is stored as `double`. + +Notes + +- Numbers with a decimal digit or scientific notation are always stored as `double`. +- The number types can be changed, see [Template number types](#template-number-types). +- As of version 3.9.1, the conversion is realized by [`std::strtoull`](https://en.cppreference.com/w/cpp/string/byte/strtoul), [`std::strtoll`](https://en.cppreference.com/w/cpp/string/byte/strtol), and [`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof), respectively. + +Examples + +- Integer `-12345678912345789123456789` is smaller than `INT64_MIN` and will be stored as floating-point number `-1.2345678912345788e+25`. +- Integer `1E3` will be stored as floating-point number `1000.0`. + +### Number limits + +- Any 64-bit signed or unsigned integer can be stored without loss of precision. +- Numbers exceeding the limits of `double` (i.e., numbers that after conversion via [`std::strtod`](https://en.cppreference.com/w/cpp/string/byte/strtof) are not satisfying [`std::isfinite`](https://en.cppreference.com/w/cpp/numeric/math/isfinite) such as `1E400`) will throw exception [`json.exception.out_of_range.406`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range406) during parsing. +- Floating-point numbers are rounded to the next number representable as `double`. For instance `3.141592653589793238462643383279` is stored as [`0x400921fb54442d18`](https://float.exposed/0x400921fb54442d18). This is the same behavior as the code `double x = 3.141592653589793238462643383279;`. + +Interoperability + +- The library is interoperable with respect to the specification, because its supported range [-2^{63}, 2^{64}-1] is larger than the described range [-2^{53}+1, 2^{53}-1]. +- All integers outside the range [-2^{63}, 2^{64}-1], as well as floating-point numbers are stored as `double`. This also concurs with the specification above. + +### Zeros + +The JSON number grammar allows for different ways to express zero, and this library will store zeros differently: + +| Literal | Stored value and type | Serialization | +| ------- | --------------------- | ------------- | +| `0` | `std::uint64_t(0)` | `0` | +| `-0` | `std::int64_t(0)` | `0` | +| `0.0` | `double(0.0)` | `0.0` | +| `-0.0` | `double(-0.0)` | `-0.0` | +| `0E0` | `double(0.0)` | `0.0` | +| `-0E0` | `double(-0.0)` | `-0.0` | + +That is, `-0` is stored as a signed integer, but the serialization does not reproduce the `-`. + +### Number serialization + +- Integer numbers are serialized as is; that is, no scientific notation is used. +- Floating-point numbers are serialized as specified by the `%g` printf modifier with [`std::numeric_limits::max_digits10`](https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10) significant digits. The rationale is to use the shortest representation while still allowing round-tripping. + +Notes regarding precision of floating-point numbers + +As described above, floating-point numbers are rounded to the nearest double and serialized with the shortest representation to allow round-tripping. This can yield confusing examples: + +- The serialization can have fewer decimal places than the input: `2555.5599999999999` will be serialized as `2555.56`. The reverse can also be true. + +- The serialization can be in scientific notation even if the input is not: `0.0000972439793401814` will be serialized as `9.72439793401814e-05`. The reverse can also be true: `12345E-5` will be serialized as `0.12345`. + +- Conversions from `float` to `double` can also introduce rounding errors: + + ``` + float f = 0.3; + json j = f; + std::cout << j << '\n'; + ``` + + yields `0.30000001192092896`. + +All examples here can be reproduced by passing the original double value to + +``` +std::printf("%.*g\n", std::numeric_limits::max_digits10, double_value); +``` + +#### NaN handling + +NaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded: + +[RFC 8259](https://tools.ietf.org/html/rfc8259#section-6), Section 6 + +Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted. + +That is, there is no way to *parse* a NaN value. However, assignments can store NaN values in a JSON value. + +This library serializes NaN values as `null`. This corresponds to the behavior of JavaScript's [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) function. + +Example + +The following example shows how a NaN value is stored in a `json` value. + +``` +int main() +{ + double val = std::numeric_limits::quiet_NaN(); + std::cout << "val=" << val << std::endl; + json j = val; + std::cout << "j=" << j.dump() << std::endl; + val = j; + std::cout << "val=" << val << std::endl; +} +``` + +output: + +``` +val=nan +j=null +val=nan +``` + +### Number comparison + +Floating-point numbers inside JSON values are compared with `json::number_float_t::operator==` which is `double::operator==` by default. + +Alternative comparison functions + +To compare floating-point while respecting an epsilon, an alternative [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) could be used, for instance + +``` +template::value, T>::type> +inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept +{ + return std::abs(a - b) <= epsilon; +} +``` + +Or you can self-define an operator equal function like this: + +``` +bool my_equal(const_reference lhs, const_reference rhs) +{ + const auto lhs_type = lhs.type(); + const auto rhs_type = rhs.type(); + if (lhs_type == rhs_type) + { + switch(lhs_type) + { + // self_defined case + case value_t::number_float: + return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); + + // other cases remain the same with the original + ... + } + } + ... +} +``` + +(see [#703](https://github.com/nlohmann/json/issues/703) for more information.) + +Note + +NaN values never compare equal to themselves or to other NaN values. See [#514](https://github.com/nlohmann/json/issues/514). + +### Number conversion + +Just like the C++ language itself, the `get` family of functions allows conversions between unsigned and signed integers, and between integers and floating-point values. This behavior may be surprising. + +Unconditional number conversions + +``` +double d = 42.3; // non-integer double value 42.3 +json jd = d; // stores double value 42.3 +std::int64_t i = jd.get(); // now i==42; no warning or error is produced +``` + +Note the last line with throw a [`json.exception.type_error.302`](https://json.nlohmann.me/home/exceptions/#jsonexceptiontype_error302) exception if `jd` is not a numerical type, for instance a string. + +Numeric conversions are performed according to the corresponding C++ conversion rules. The library does not perform range checks when converting between numeric types. + +In particular, conversions from floating-point values to integer types, or conversions to integer types with a smaller range than the stored value, may produce implementation-defined or undefined behavior if the source value cannot be represented by the target type. + +Applications requiring checked conversions should inspect the stored number type with [`is_number_float()`](https://json.nlohmann.me/api/basic_json/is_number_float/index.md), [`is_number_integer()`](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md), [`is_number_unsigned()`](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md), or [`type()`](https://json.nlohmann.me/api/basic_json/type/index.md), and perform explicit range checks before converting to a narrower type. + +The rationale is twofold: + +1. JSON does not define a number type or precision (see above). +1. C++ also allows silently converting between number types. + +Conditional number conversion + +The code above can be solved by explicitly checking the nature of the value with members such as [`is_number_integer()`](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) or [`is_number_unsigned()`](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md): + +``` +// check if jd is really integer-valued +if (jd.is_number_integer()) +{ + // if so, do the conversion and use i + std::int64_t i = jd.get(); + // ... +} +else +{ + // otherwise, take appropriate action + // ... +} +``` + +Note this approach also has the advantage that it can react on non-numerical JSON value types such as strings. + +(Example taken from [#777](https://github.com/nlohmann/json/issues/777#issuecomment-459968458).) + +### Determine number types + +As the example in [Number conversion](#number-conversion) shows, there are different functions to determine the type of the stored number: + +- [`is_number()`](https://json.nlohmann.me/api/basic_json/is_number/index.md) returns `true` for any number type +- [`is_number_integer()`](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) returns `true` for signed and unsigned integers +- [`is_number_unsigned()`](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md) returns `true` for unsigned integers only +- [`is_number_float()`](https://json.nlohmann.me/api/basic_json/is_number_float/index.md) returns `true` for floating-point numbers +- [`type_name()`](https://json.nlohmann.me/api/basic_json/type_name/index.md) returns `"number"` for any number type +- [`type()`](https://json.nlohmann.me/api/basic_json/type/index.md) returns a different enumerator of [`value_t`](https://json.nlohmann.me/api/basic_json/value_t/index.md) for all number types + +| function | unsigned integer | signed integer | floating-point | string | +| --------------------------------------------------------------------------------------------- | ----------------- | ---------------- | -------------- | ---------- | +| [`is_number()`](https://json.nlohmann.me/api/basic_json/is_number/index.md) | `true` | `true` | `true` | `false` | +| [`is_number_integer()`](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) | `true` | `true` | `false` | `false` | +| [`is_number_unsigned()`](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md) | `true` | `false` | `false` | `false` | +| [`is_number_float()`](https://json.nlohmann.me/api/basic_json/is_number_float/index.md) | `false` | `false` | `true` | `false` | +| [`type_name()`](https://json.nlohmann.me/api/basic_json/type_name/index.md) | `"number"` | `"number"` | `"number"` | `"string"` | +| [`type()`](https://json.nlohmann.me/api/basic_json/type/index.md) | `number_unsigned` | `number_integer` | `number_float` | `string` | + +### Template number types + +The number types can be changed with template parameters. + +| position | number type | default type | possible values | +| -------- | ----------------- | --------------- | -------------------------------------- | +| 5 | signed integers | `std::int64_t` | `std::int32_t`, `std::int16_t`, etc. | +| 6 | unsigned integers | `std::uint64_t` | `std::uint32_t`, `std::uint16_t`, etc. | +| 7 | floating-point | `double` | `float`, `long double` | + +Constraints on number types + +- The type for signed integers must be convertible from `long long`. The type for floating-point numbers is used in case of overflow. +- The type for unsigned integers must be convertible from `unsigned long long`. The type for floating-point numbers is used in case of overflow. +- The types for signed and unsigned integers must be distinct, see [#2573](https://github.com/nlohmann/json/issues/2573). +- Only `double`, `float`, and `long double` are supported for floating-point numbers. + +Example + +A `basic_json` type that uses `long double` as floating-point type. + +``` +using json_ld = nlohmann::basic_json; +``` + +Note values should then be parsed with `json_ld::parse` rather than `json::parse` as the latter would parse floating-point values to `double` before then converting them to `long double`. diff --git a/home/architecture.md b/home/architecture.md new file mode 100644 index 000000000..aba2be580 --- /dev/null +++ b/home/architecture.md @@ -0,0 +1,124 @@ +# Architecture + +!!! info + + This page is still under construction. Its goal is to provide a high-level overview of the library's architecture. + This should help new contributors to get an idea of the used concepts and where to make changes. + +## Overview + +The main structure is class [nlohmann::basic_json](../api/basic_json/index.md). + +- public API +- container interface +- iterators + +## Template specializations + +- describe template parameters of `basic_json` +- [`json`](../api/json.md) +- [`ordered_json`](../api/ordered_json.md) via [`ordered_map`](../api/ordered_map.md) + +## Value storage + +Values are stored as a tagged union of [value_t](../api/basic_json/value_t.md) and json_value. + +```cpp +/// the type of the current element +value_t m_type = value_t::null; + +/// the value of the current element +json_value m_value = {}; +``` + +with + +```cpp +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function +}; + +union json_value { + /// object (stored with pointer to save storage) + object_t *object; + /// array (stored with pointer to save storage) + array_t *array; + /// string (stored with pointer to save storage) + string_t *string; + /// binary (stored with pointer to save storage) + binary_t *binary; + /// boolean + boolean_t boolean; + /// number (integer) + number_integer_t number_integer; + /// number (unsigned integer) + number_unsigned_t number_unsigned; + /// number (floating-point) + number_float_t number_float; +}; +``` + +## Parsing inputs (deserialization) + +Input is read via **input adapters** that abstract a source with a common interface: + +```cpp +/// read a single character +std::char_traits::int_type get_character() noexcept; + +/// read multiple characters to a destination buffer and +/// returns the number of characters successfully read +template +std::size_t get_elements(T* dest, std::size_t count = 1); +``` + +List examples of input adapters. + +## SAX Interface + +TODO + +## Writing outputs (serialization) + +Output is written via **output adapters**: + +```cpp +template +void write_character(CharType c); + +template +void write_characters(const CharType* s, std::size_t length); +``` + +List examples of output adapters. + +## Value conversion + +```cpp +template +void to_json(basic_json& j, const T& t); + +template +void from_json(const basic_json& j, T& t); +``` + +## Additional features + +- JSON Pointers +- Binary formats +- Custom base class +- Conversion macros + +## Details namespace + +- C++ feature backports diff --git a/home/architecture/index.html b/home/architecture/index.html index 5f0ac8998..96260d2fe 100644 --- a/home/architecture/index.html +++ b/home/architecture/index.html @@ -52,4 +52,4 @@ template<class T> void from_json(const basic_json& j, T& t); -

    Additional features

    • JSON Pointers
    • Binary formats
    • Custom base class
    • Conversion macros

    Details namespace

    • C++ feature backports
    \ No newline at end of file +

    Additional features

    • JSON Pointers
    • Binary formats
    • Custom base class
    • Conversion macros

    Details namespace

    • C++ feature backports
    \ No newline at end of file diff --git a/home/architecture/index.md b/home/architecture/index.md new file mode 100644 index 000000000..6457de021 --- /dev/null +++ b/home/architecture/index.md @@ -0,0 +1,123 @@ +# Architecture + +Info + +This page is still under construction. Its goal is to provide a high-level overview of the library's architecture. This should help new contributors to get an idea of the used concepts and where to make changes. + +## Overview + +The main structure is class [nlohmann::basic_json](https://json.nlohmann.me/api/basic_json/index.md). + +- public API +- container interface +- iterators + +## Template specializations + +- describe template parameters of `basic_json` +- [`json`](https://json.nlohmann.me/api/json/index.md) +- [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) via [`ordered_map`](https://json.nlohmann.me/api/ordered_map/index.md) + +## Value storage + +Values are stored as a tagged union of [value_t](https://json.nlohmann.me/api/basic_json/value_t/index.md) and json_value. + +``` +/// the type of the current element +value_t m_type = value_t::null; + +/// the value of the current element +json_value m_value = {}; +``` + +with + +``` +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function +}; + +union json_value { + /// object (stored with pointer to save storage) + object_t *object; + /// array (stored with pointer to save storage) + array_t *array; + /// string (stored with pointer to save storage) + string_t *string; + /// binary (stored with pointer to save storage) + binary_t *binary; + /// boolean + boolean_t boolean; + /// number (integer) + number_integer_t number_integer; + /// number (unsigned integer) + number_unsigned_t number_unsigned; + /// number (floating-point) + number_float_t number_float; +}; +``` + +## Parsing inputs (deserialization) + +Input is read via **input adapters** that abstract a source with a common interface: + +``` +/// read a single character +std::char_traits::int_type get_character() noexcept; + +/// read multiple characters to a destination buffer and +/// returns the number of characters successfully read +template +std::size_t get_elements(T* dest, std::size_t count = 1); +``` + +List examples of input adapters. + +## SAX Interface + +TODO + +## Writing outputs (serialization) + +Output is written via **output adapters**: + +``` +template +void write_character(CharType c); + +template +void write_characters(const CharType* s, std::size_t length); +``` + +List examples of output adapters. + +## Value conversion + +``` +template +void to_json(basic_json& j, const T& t); + +template +void from_json(const basic_json& j, T& t); +``` + +## Additional features + +- JSON Pointers +- Binary formats +- Custom base class +- Conversion macros + +## Details namespace + +- C++ feature backports diff --git a/home/customers.md b/home/customers.md new file mode 100644 index 000000000..73ac83ee8 --- /dev/null +++ b/home/customers.md @@ -0,0 +1,178 @@ +# Customers + +The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but +the result of an internet search. If you know further customers of the library, [please let me know](mailto:mail@nlohmann.me). + +[![](../images/customers.png)](../images/customers.png) + +## Space Exploration + +- [**Peregrine Lunar Lander Flight 01**](https://en.wikipedia.org/wiki/Peregrine_Mission_One) - The library was used for payload management in the **Peregrine Moon Lander**, developed by **Astrobotic Technology** and launched as part of NASA's **Commercial Lunar Payload Services (CLPS)** program. After six days in orbit, the spacecraft was intentionally redirected into Earth's atmosphere, where it burned up over the Pacific Ocean on **January 18, 2024**. + +## Automotive + +- [**Alexa Auto SDK**](https://github.com/alexa/alexa-auto-sdk), a software development kit enabling the integration of Alexa into automotive systems +- [**Apollo**](https://github.com/ApolloAuto/apollo), a framework for building autonomous driving systems +- [**Automotive Grade Linux (AGL)**](https://download.automotivelinux.org/AGL/release/jellyfish/latest/qemux86-64/deploy/licenses/nlohmann-json/), a collaborative open-source platform for automotive software development +- [**Genesis Motor** (infotainment)](http://webmanual.genesis.com/ccIC/AVNT/JW/KOR/English/reference010.html), a luxury automotive brand +- [**Hyundai** (infotainment)](https://www.hyundai.com/wsvc/ww/download.file.do?id=/content/hyundai/ww/data/opensource/data/GN7-2022/licenseCode/info), a global automotive brand +- [**Kia** (infotainment)](http://webmanual.kia.com/PREM_GEN6/AVNT/RJPE/KOR/Korean/reference010.html), a global automotive brand +- [**Mercedes-Benz Operating System (MB.OS)**](https://group.mercedes-benz.com/careers/about-us/mercedes-benz-operating-system/), a core component of the vehicle software ecosystem from Mercedes-Benz +- [**Rivian** (infotainment)](https://assets.ctfassets.net/2md5qhoeajym/3cwyo4eoufk4yingUwusFt/ded2c47da620fdfc99c88c7156d2c1d8/In-Vehicle_OSS_Attribution_2024__11-24_.pdf), an electric vehicle manufacturer +- [**Suzuki** (infotainment)](https://www.globalsuzuki.com/motorcycle/ipc/oss/oss_48KA_00.pdf), a global automotive and motorcycle manufacturer + +## Gaming and Entertainment + +- [**Assassin's Creed: Mirage**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a stealth-action game set in the Middle East, focusing on the journey of a young assassin with classic parkour and stealth mechanics +- [**Chasm: The Rift**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a first-person shooter blending horror and adventure, where players navigate dark realms and battle monsters +- [**College Football 25**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a college football simulation game featuring gameplay that mimics real-life college teams and competitions +- [**Concepts**](https://concepts.app/en/licenses), a digital sketching app designed for creative professionals, offering flexible drawing tools for illustration, design, and brainstorming +- [**Depthkit**](https://www.depthkit.tv/third-party-licenses), a tool for creating and capturing volumetric video, enabling immersive 3D experiences and interactive content +- [**IMG.LY**](https://img.ly/acknowledgements), a platform offering creative tools and SDKs for integrating advanced image and video editing in applications +- [**LOOT**](https://loot.readthedocs.io/_/downloads/en/0.13.0/pdf/), a tool for optimizing the load order of game plugins, commonly used in The Elder Scrolls and Fallout series +- [**Madden NFL 25**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a sports simulation game capturing the excitement of American football with realistic gameplay and team management features +- [**Marne**](https://marne.io/licenses), an unofficial private server platform for hosting custom Battlefield 1 game experiences +- [**Minecraft**](https://www.minecraft.net/zh-hant/attribution), a popular sandbox video game +- [**NHL 22**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a hockey simulation game offering realistic gameplay, team management, and various modes to enhance the hockey experience +- [**Pixelpart**](https://pixelpart.net/documentation/book/third-party.html), a 2D animation and video compositing software that allows users to create animated graphics and visual effects with a focus on simplicity and ease of use +- [**Razer Cortex**](https://mysupport.razer.com/app/answers/detail/a_id/14146/~/open-source-software-for-razer-software), a gaming performance optimizer and system booster designed to enhance the gaming experience +- [**Red Dead Redemption II**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), an open-world action-adventure game following an outlaw's story in the late 1800s, emphasizing deep storytelling and immersive gameplay +- [**Snapchat**](https://www.snap.com/terms/license-android), a multimedia messaging and augmented reality app for communication and entertainment +- [**Tactics Ogre: Reborn**](https://www.square-enix-games.com/en_US/documents/tactics-ogre-reborn-pc-installer-software-and-associated-plug-ins-disclosure), a tactical role-playing game featuring strategic battles and deep storytelling elements +- [**Throne and Liberty**](https://www.amazon.com/gp/help/customer/display.html?nodeId=T7fLNw5oAevCMtJFPj&pop-up=1), an MMORPG that offers an expansive fantasy world with dynamic gameplay and immersive storytelling +- [**Unity Vivox**](https://docs.unity3d.com/Packages/com.unity.services.vivox@15.1/license/Third%20Party%20Notices.html), a communication service that enables voice and text chat functionality in multiplayer games developed with Unity +- [**Zool: Redimensioned**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a modern reimagining of the classic platformer featuring fast-paced gameplay and vibrant environments +- [**immersivetech**](https://immersitech.io/open-source-third-party-software/), a technology company focused on immersive experiences, providing tools and solutions for virtual and augmented reality applications + +## Consumer Electronics + +- [**Audinate**](https://www.audinate.com/legal/software-licensing/dante-av-h-open-source-licenses/), a provider of networked audio solutions specializing in Dante technology, which facilitates high-quality digital audio transport over IP networks +- [**Canon CanoScan LIDE**](https://carolburo.com/wp-content/uploads/2024/06/LiDE400_OnlineManual_Win_FR_V02.pdf), a series of flatbed scanners offering high-resolution image scanning for home and office use +- [**Canon PIXMA Printers**](https://www.mediaexpert.pl/products/files/73/7338196/Instrukcja-obslugi-CANON-Pixma-TS7450i.pdf), a line of all-in-one inkjet printers known for high-quality printing and wireless connectivity +- [**Cisco Webex Desk Camera**](https://www.cisco.com/c/dam/en_us/about/doing_business/open_source/docs/CiscoWebexDeskCamera-23-1622100417.pdf), a video camera designed for professional-quality video conferencing and remote collaboration +- [**Philips Hue Personal Wireless Lighting**](http://2ak5ape.257.cz/), a smart lighting system for customizable and wireless home illumination +- [**Ray-Ban Meta Smart glasses**](https://www.meta.com/de/en/legal/smart-glasses/third-party-notices-android/03/), a pair of smart glasses designed for capturing photos and videos with integrated connectivity and social features +- [**Razer Synapse**](https://mysupport.razer.com/app/answers/detail/a_id/14146/~/open-source-software-for-razer-software), a unified configuration software enabling hardware customization for Razer devices +- [**Siemens SINEMA Remote Connect**](https://cache.industry.siemens.com/dl/files/790/109793790/att_1054961/v2/OSS_SINEMA-RC_86.pdf), a remote connectivity solution for monitoring and managing industrial networks and devices securely +- [**Sony PlayStation 4**](https://doc.dl.playstation.net/doc/ps4-oss/index.html), a gaming console developed by Sony that offers a wide range of games and multimedia entertainment features +- [**Sony Virtual Webcam Driver for Remote Camera**](https://helpguide.sony.net/rc/vwd/v1/zh-cn/print.pdf), a software driver that enables the use of Sony cameras as virtual webcams for video conferencing and streaming + +## Operating Systems + +- [**Apple iOS and macOS**](https://www.apple.com/macos), a family of operating systems developed by Apple, including iOS for mobile devices and macOS for desktop computers +- [**Google Fuchsia**](https://fuchsia.googlesource.com/third_party/json/), an open-source operating system developed by Google, designed to be secure, updatable, and adaptable across various devices +- [**SerenityOS**](https://github.com/SerenityOS/serenity), an open-source operating system that aims to provide a simple and beautiful user experience with a focus on simplicity and elegance +- [**Yocto**](http://ftp.emacinc.com/openembedded-sw/kirkstone-icop-5.15-kirkstone-6.0/archive-2024-10/pn8m-090t-ppc/licenses/nlohmann-json/), a Linux-based build system for creating custom operating systems and software distributions, tailored for embedded devices and IoT applications + +## Development Tools and IDEs + +- [**Accentize SpectralBalance**](https://www.accentize.com/products/SpectralBalanceManual.pdf), an adaptive speech analysis tool designed to enhance audio quality by optimizing frequency balance in recordings +- [**Arm Compiler for Linux**](https://documentation-service.arm.com/static/66558e9d876c8d213b7843e4), a software development toolchain for compiling and optimizing applications on Arm-based Linux systems +- [**BBEdit**](https://s3.amazonaws.com/BBSW-download/BBEdit_15.1.2_User_Manual.pdf), a professional text and code editor for macOS +- [**CoderPad**](https://coderpad.io), a collaborative coding platform that enables real-time code interviews and assessments for developers; the library is included in every CoderPad instance and can be accessed with a simple `#include "json.hpp"` +- [**Compiler Explorer**](https://godbolt.org), a web-based tool that allows users to write, compile, and visualize the assembly output of code in various programming languages; the library is readily available and accessible with the directive `#include `. +- [**GitHub CodeQL**](https://github.com/github/codeql), a code analysis tool used for identifying security vulnerabilities and bugs in software through semantic queries +- [**Hex-Rays**](https://docs.hex-rays.com/user-guide/user-interface/licenses), a reverse engineering toolset for analyzing and decompiling binaries, primarily used for security research and vulnerability analysis +- [**ImHex**](https://github.com/WerWolv/ImHex), a hex editor designed for reverse engineering, providing advanced features for data analysis and manipulation +- [**Intel GPA Framework**](https://intel.github.io/gpasdk-doc/src/licenses.html), a suite of cross-platform tools for capturing, analyzing, and optimizing graphics applications across different APIs +- [**Intopix**](https://www.intopix.com/software-licensing), a provider of advanced image processing and compression solutions used in software development and AV workflows +- [**Java SE**](https://www.oracle.com/a/tech/docs/jdk8-lium.pdf), the core Java platform that provides the libraries and runtime needed to build and run general-purpose Java applications +- [**MKVToolNix**](https://mkvtoolnix.download/doc/README.md), a set of tools for creating, editing, and inspecting MKV (Matroska) multimedia container files +- [**Meta Yoga**](https://github.com/facebook/yoga), a layout engine that facilitates flexible and efficient user interface design across multiple platforms +- [**NVIDIA Nsight Compute**](https://docs.nvidia.com/nsight-compute/2022.2/pdf/CopyrightAndLicenses.pdf), a performance analysis tool for CUDA applications that provides detailed insights into GPU performance metrics +- [**Notepad++**](https://github.com/notepad-plus-plus/notepad-plus-plus), a free source code editor that supports various programming languages +- [**OpenRGB**](https://gitlab.com/CalcProgrammer1/OpenRGB), an open source RGB lighting control that doesn't depend on manufacturer software +- [**OpenTelemetry C++**](https://github.com/open-telemetry/opentelemetry-cpp), a library for collecting and exporting observability data in C++, enabling developers to implement distributed tracing and metrics in their application +- [**Qt Creator**](https://doc.qt.io/qtcreator/qtcreator-attribution-json-nlohmann.html), an IDE for developing applications using the Qt application framework +- [**Scanbot SDK**](https://docs.scanbot.io/barcode-scanner-sdk/web/third-party-libraries/), a software development kit (SDK) that provides tools for integrating advanced document scanning and barcode scanning capabilities into applications + +## Machine Learning and AI + +- [**Apple Core ML Tools**](https://github.com/apple/coremltools), a set of tools for converting and configuring machine learning models for deployment in Apple's Core ML framework +- [**Avular Mobile Robotics**](https://www.avular.com/licenses/nlohmann-json-3.9.1.txt), a platform for developing and deploying mobile robotics solutions +- [**Google gemma.cpp**](https://github.com/google/gemma.cpp), a lightweight C++ inference engine designed for running AI models from the Gemma family +- [**llama.cpp**](https://github.com/ggerganov/llama.cpp), a C++ library designed for efficient inference of large language models (LLMs), enabling streamlined integration into applications +- [**MLX**](https://github.com/ml-explore/mlx), an array framework for machine learning on Apple Silicon +- [**Mozilla llamafile**](https://github.com/Mozilla-Ocho/llamafile), a tool designed for distributing and executing large language models (LLMs) efficiently using a single file format +- [**NVIDIA ACE**](https://docs.nvidia.com/ace/latest/index.html), a suite of real-time AI solutions designed for the development of interactive avatars and digital human applications, enabling scalable and sophisticated user interactions +- [**Peer**](https://support.peer.inc/hc/en-us/articles/17261335054235-Licenses), a platform offering personalized AI assistants for interactive learning and creative collaboration +- [**stable-diffusion.cpp**](https://github.com/leejet/stable-diffusion.cpp), a C++ implementation of the Stable Diffusion image generation model +- [**TanvasTouch**](https://tanvas.co/tanvastouch-sdk-third-party-acknowledgments), a software development kit (SDK) that enables developers to create tactile experiences on touchscreens, allowing users to feel textures and physical sensations in a digital environment +- [**TensorFlow**](https://github.com/tensorflow/tensorflow), a machine learning framework that facilitates the development and training of models, supporting data serialization and efficient data exchange between components + +## Scientific Research and Analysis + +- [**BLACK**](https://www.black-sat.org/en/stable/installation/linux.html), a bounded linear temporal logic (LTL) satisfiability checker +- [**CERN Atlas Athena**](https://gitlab.cern.ch/atlas/athena/-/blob/main/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonMTSvc.h), a software framework used in the ATLAS experiment at the Large Hadron Collider (LHC) for performance monitoring +- [**ICU**](https://github.com/unicode-org/icu), the International Components for Unicode, a mature library for software globalization and multilingual support +- [**KAMERA**](https://github.com/Kitware/kamera), a platform for synchronized data collection and real-time deep learning to map marine species like polar bears and seals, aiding Arctic ecosystem research +- [**KiCad**](https://gitlab.com/kicad/code/kicad/-/tree/master/thirdparty/nlohmann_json), a free and open-source software suite for electronic design automation +- [**Maple**](https://www.maplesoft.com/support/help/Maple/view.aspx?path=copyright), a symbolic and numeric computing environment for advanced mathematical modeling and analysis +- [**MeVisLab**](https://mevislabdownloads.mevis.de/docs/current/MeVis/ThirdParty/Documentation/Publish/ThirdPartyReference/index.html), a software framework for medical image processing and visualization. +- [**OpenPMD API**](https://openpmd-api.readthedocs.io/en/0.8.0-alpha/backends/json.html), a versatile programming interface for accessing and managing scientific data, designed to facilitate the efficient storage, retrieval, and sharing of simulation data across various applications and platforms +- [**ParaView**](https://github.com/Kitware/ParaView), an open-source tool for large-scale data visualization and analysis across various scientific domains +- [**QGIS**](https://gitlab.b-data.ch/qgis/qgis/-/blob/backport-57658-to-release-3_34/external/nlohmann/json.hpp), a free and open-source geographic information system (GIS) application that allows users to create, edit, visualize, and analyze geospatial data across a variety of formats +- [**VTK**](https://github.com/Kitware/VTK), a software library for 3D computer graphics, image processing, and visualization +- [**VolView**](https://github.com/Kitware/VolView), a lightweight application for interactive visualization and analysis of 3D medical imaging data. + +## Business and Productivity Software + +- [**ArcGIS PRO**](https://www.esri.com/content/dam/esrisites/en-us/media/legal/open-source-acknowledgements/arcgis-pro-2-8-attribution-report.html), a desktop geographic information system (GIS) application developed by Esri for mapping and spatial analysis +- [**Autodesk Desktop**](https://damassets.autodesk.net/content/dam/autodesk/www/Company/legal-notices-trademarks/autodesk-desktop-platform-components/internal-autodesk-components-web-page-2023.pdf), a software platform developed by Autodesk for creating and managing desktop applications and services +- [**Check Point**](https://www.checkpoint.com/about-us/copyright-and-trademarks/), a cybersecurity company specializing in threat prevention and network security solutions, offering a range of products designed to protect enterprises from cyber threats and ensure data integrity +- [**Microsoft Office for Mac**](https://officecdnmac.microsoft.com/pr/legal/mac/OfficeforMacAttributions.html), a suite of productivity applications developed by Microsoft for macOS, including tools for word processing, spreadsheets, and presentations +- [**Microsoft Teams**](https://www.microsoft.com/microsoft-teams/), a team collaboration application offering workspace chat and video conferencing, file storage, and integration of proprietary and third-party applications and services +- [**Nexthink Infinity**](https://docs.nexthink.com/legal/services-terms/experience-open-source-software-licenses/infinity-2022.8-software-licenses), a digital employee experience management platform for monitoring and improving IT performance +- [**Sophos Connect Client**](https://docs.sophos.com/nsg/licenses/SophosConnect/SophosConnectAttribution.html), a secure VPN client from Sophos that allows remote users to connect to their corporate network, ensuring secure access to resources and data +- [**Stonebranch**](https://stonebranchdocs.atlassian.net/wiki/spaces/UA77/pages/799545647/Licenses+for+Third-Party+Libraries), a cloud-based cybersecurity solution that integrates backup, disaster recovery, and cybersecurity features to protect data and ensure business continuity for organizations +- [**Tablecruncher**](https://tablecruncher.com/), a data analysis tool that allows users to import, analyze, and visualize spreadsheet data, offering interactive features for better insights and decision-making +- [**magicplan**](https://help.magicplan.app/acknowledgments), a mobile application for creating floor plans and interior designs using augmented reality + +## Databases and Big Data + +- [**ADIOS2**](https://code.ornl.gov/ecpcitest/adios2/-/tree/pr4285_FFSUpstream/thirdparty/nlohmann_json?ref_type=heads), a data management framework designed for high-performance input and output operations +- [**Cribl Stream**](https://docs.cribl.io/stream/third-party-current-list/), a real-time data processing platform that enables organizations to collect, route, and transform observability data, enhancing visibility and insights into their systems +- [**DB Browser for SQLite**](https://github.com/sqlitebrowser/sqlitebrowser), a visual open-source tool for creating, designing, and editing SQLite database files +- [**MySQL Connector/C++**](https://docs.oracle.com/cd/E17952_01/connector-cpp-9.1-license-com-en/license-opentelemetry-cpp-com.html), a C++ library for connecting and interacting with MySQL databases +- [**MySQL NDB Cluster**](https://downloads.mysql.com/docs/licenses/cluster-9.0-com-en.pdf), a distributed database system that provides high availability and scalability for MySQL databases +- [**MySQL Shell**](https://downloads.mysql.com/docs/licenses/mysql-shell-8.0-gpl-en.pdf), an advanced client and code editor for interacting with MySQL servers, supporting SQL, Python, and JavaScript +- [**PrestoDB**](https://github.com/prestodb/presto), a distributed SQL query engine designed for large-scale data analytics, originally developed by Facebook +- [**ROOT Data Analysis Framework**](https://root.cern/doc/v614/classnlohmann_1_1basic__json.html), an open-source data analysis framework widely used in high-energy physics and other fields for data processing and visualization +- [**WiredTiger**](https://github.com/wiredtiger/wiredtiger), a high-performance storage engine for databases, offering support for compression, concurrency, and checkpointing + +## Simulation and Modeling + +- [**Arcturus HoloSuite**](https://www.datocms-assets.com/104353/1698904597-holosuite-third-party-software-credits-and-attributions-2.pdf), a software toolset for capturing, editing, and streaming volumetric video, featuring advanced compression technologies for high-quality 3D content creation +- [**azul**](https://pure.tudelft.nl/ws/files/85338589/tgis.12673.pdf), a fast and efficient 3D city model viewer designed for visualizing urban environments and spatial data +- [**Blender**](https://projects.blender.org/blender/blender/search?q=nlohmann), a free and open-source 3D creation suite for modeling, animation, rendering, and more +- [**cpplot**](https://cpplot.readthedocs.io/en/latest/library_api/function_eigen_8h_1ac080eac0541014c5892a55e41bf785e6.html), a library for creating interactive graphs and charts in C++, which can be viewed in web browsers +- [**Foundry Nuke**](https://learn.foundry.com/nuke/content/misc/studio_third_party_libraries.html), a powerful node-based digital compositing and visual effects application used in film and television post-production +- [**GAMS**](https://www.gams.com/47/docs/THIRDPARTY.html), a high-performance mathematical modeling system for optimization and decision support +- [**Kitware SMTK**](https://github.com/Kitware/SMTK), a software toolkit for managing simulation models and workflows in scientific and engineering applications +- [**M-Star**](https://docs.mstarcfd.com/3_Licensing/thirdparty-licenses.html), a computational fluid dynamics software for simulating and analyzing fluid flow +- [**MapleSim CAD Toolbox**](https://www.maplesoft.com/support/help/MapleSim/view.aspx?path=CADToolbox/copyright), a software extension for MapleSim that integrates CAD models, allowing users to import, manipulate, and analyze 3D CAD data within the MapleSim environment for enhanced modeling and simulation +- [**NVIDIA Omniverse**](https://docs.omniverse.nvidia.com/composer/latest/common/product-licenses/usd-explorer/usd-explorer-2023.2.0-licenses-manifest.html), a platform for 3D content creation and collaboration that enables real-time simulations and interactive experiences across various industries +- [**Pixar Renderman**](https://rmanwiki-26.pixar.com/space/REN26/19662083/Legal+Notice), a photorealistic 3D rendering software developed by Pixar, widely used in the film industry for creating high-quality visual effects and animations +- [**ROS - Robot Operating System**](http://docs.ros.org/en/noetic/api/behaviortree_cpp/html/json_8hpp_source.html), a set of software libraries and tools that assist in developing robot applications +- [**UBS**](https://www.ubs.com/), a multinational financial services and banking company + +## Enterprise and Cloud Applications + +- [**Acronis Cyber Protect Cloud**](https://care.acronis.com/s/article/59533-Third-party-software-used-in-Acronis-Cyber-Protect-Cloud?language=en_US), an all-in-one data protection solution that combines backup, disaster recovery, and cybersecurity to safeguard business data from threats like ransomware +- [**Baereos**](https://gitlab.tiger-computing.co.uk/packages/bareos/-/blob/tiger/bullseye/third-party/CLI11/examples/json.cpp), a backup solution that provides data protection and recovery options for various environments, including physical and virtual systems +- [**Bitdefender Home Scanner**](https://www.bitdefender.de/site/Main/view/home-scanner-open-source.html), a tool from Bitdefender that scans devices for malware and security threats, providing a safeguard against potential online dangers +- [**Citrix Provisioning**](https://docs.citrix.com/en-us/provisioning/2203-ltsr/downloads/pvs-third-party-notices-2203.pdf), a solution that streamlines the delivery of virtual desktops and applications by allowing administrators to manage and provision resources efficiently across multiple environments +- [**Citrix Virtual Apps and Desktops**](https://docs.citrix.com/en-us/citrix-virtual-apps-desktops/2305/downloads/third-party-notices-apps-and-desktops.pdf), a solution from Citrix that delivers virtual apps and desktops +- [**Cyberarc**](https://docs.cyberark.com/Downloads/Legal/Privileged%20Session%20Manager%20for%20SSH%20Third-Party%20Notices.pdf), a security solution that specializes in privileged access management, enabling organizations to control and monitor access to critical systems and data, thereby enhancing overall cybersecurity posture +- [**Egnyte Desktop**](https://helpdesk.egnyte.com/hc/en-us/articles/360007071732-Third-Party-Software-Acknowledgements), a secure cloud storage solution designed for businesses, enabling file sharing, collaboration, and data management across teams while ensuring compliance and data protection +- [**Elster**](https://www.secunet.com/en/about-us/press/article/elstersecure-bietet-komfortablen-login-ohne-passwort-dank-secunet-protect4use), a digital platform developed by German tax authorities for secure and efficient electronic tax filing and management using secunet protect4use +- [**Ethereum Solidity**](https://github.com/ethereum/solidity), a high-level, object-oriented programming language designed for implementing smart contracts on the Ethereum platform +- [**Inciga**](https://fossies.org/linux/icinga2/third-party/nlohmann_json/json.hpp), a monitoring tool for IT infrastructure, designed to provide insights into system performance and availability through customizable dashboards and alerts +- [**Intel Accelerator Management Daemon for VMware ESXi**](https://downloadmirror.intel.com/772507/THIRD-PARTY.txt), a management tool designed for monitoring and controlling Intel hardware accelerators within VMware ESXi environments, optimizing performance and resource allocation +- [**Juniper Identity Management Service**](https://www.juniper.net/documentation/us/en/software/jims/jims-guide/jims-guide.pdf) +- [**Microsoft Azure IoT SDK**](https://library.e.abb.com/public/2779c5f85f30484192eb3cb3f666a201/IP%20Gateway%20Open%20License%20Declaration_9AKK108467A4095_Rev_C.pdf), a collection of tools and libraries to help developers connect, build, and deploy Internet of Things (IoT) solutions on the Azure cloud platform +- [**Microsoft WinGet**](https://github.com/microsoft/winget-cli), a command-line utility included in the Windows Package Manager +- [**plexusAV**](https://www.sisme.com/media/10994/manual_plexusav-p-avn-4-form8244-c.pdf), a high-performance AV-over-IP transceiver device capable of video encoding and decoding using the IPMX standard +- [**Pointr**](https://docs-dev.pointr.tech/docs/8.x/Developer%20Portal/Open%20Source%20Licenses/), a platform for indoor positioning and navigation solutions, offering tools and SDKs for developers to create location-based applications +- [**secunet protect4use**](https://www.secunet.com/en/about-us/press/article/elstersecure-bietet-komfortablen-login-ohne-passwort-dank-secunet-protect4use), a secure, passwordless multifactor authentication solution that transforms smartphones into digital keyrings, ensuring high security for online services and digital identities +- [**Sencore MRD 7000**](https://www.foccusdigital.com/wp-content/uploads/2025/03/MRD-7000-Manual-8175V.pdf), a professional multi-channel receiver and decoder supporting UHD and HD stream decoding diff --git a/home/customers/index.html b/home/customers/index.html index 2cf9b2b1f..69d12b142 100644 --- a/home/customers/index.html +++ b/home/customers/index.html @@ -1 +1 @@ - Customers - JSON for Modern C++

    Customers

    The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but the result of an internet search. If you know further customers of the library, please let me know.

    Space Exploration

    • Peregrine Lunar Lander Flight 01 - The library was used for payload management in the Peregrine Moon Lander, developed by Astrobotic Technology and launched as part of NASA's Commercial Lunar Payload Services (CLPS) program. After six days in orbit, the spacecraft was intentionally redirected into Earth's atmosphere, where it burned up over the Pacific Ocean on January 18, 2024.

    Automotive

    Gaming and Entertainment

    • Assassin's Creed: Mirage, a stealth-action game set in the Middle East, focusing on the journey of a young assassin with classic parkour and stealth mechanics
    • Chasm: The Rift, a first-person shooter blending horror and adventure, where players navigate dark realms and battle monsters
    • College Football 25, a college football simulation game featuring gameplay that mimics real-life college teams and competitions
    • Concepts, a digital sketching app designed for creative professionals, offering flexible drawing tools for illustration, design, and brainstorming
    • Depthkit, a tool for creating and capturing volumetric video, enabling immersive 3D experiences and interactive content
    • IMG.LY, a platform offering creative tools and SDKs for integrating advanced image and video editing in applications
    • LOOT, a tool for optimizing the load order of game plugins, commonly used in The Elder Scrolls and Fallout series
    • Madden NFL 25, a sports simulation game capturing the excitement of American football with realistic gameplay and team management features
    • Marne, an unofficial private server platform for hosting custom Battlefield 1 game experiences
    • Minecraft, a popular sandbox video game
    • NHL 22, a hockey simulation game offering realistic gameplay, team management, and various modes to enhance the hockey experience
    • Pixelpart, a 2D animation and video compositing software that allows users to create animated graphics and visual effects with a focus on simplicity and ease of use
    • Razer Cortex, a gaming performance optimizer and system booster designed to enhance the gaming experience
    • Red Dead Redemption II, an open-world action-adventure game following an outlaw's story in the late 1800s, emphasizing deep storytelling and immersive gameplay
    • Snapchat, a multimedia messaging and augmented reality app for communication and entertainment
    • Tactics Ogre: Reborn, a tactical role-playing game featuring strategic battles and deep storytelling elements
    • Throne and Liberty, an MMORPG that offers an expansive fantasy world with dynamic gameplay and immersive storytelling
    • Unity Vivox, a communication service that enables voice and text chat functionality in multiplayer games developed with Unity
    • Zool: Redimensioned, a modern reimagining of the classic platformer featuring fast-paced gameplay and vibrant environments
    • immersivetech, a technology company focused on immersive experiences, providing tools and solutions for virtual and augmented reality applications

    Consumer Electronics

    • Audinate, a provider of networked audio solutions specializing in Dante technology, which facilitates high-quality digital audio transport over IP networks
    • Canon CanoScan LIDE, a series of flatbed scanners offering high-resolution image scanning for home and office use
    • Canon PIXMA Printers, a line of all-in-one inkjet printers known for high-quality printing and wireless connectivity
    • Cisco Webex Desk Camera, a video camera designed for professional-quality video conferencing and remote collaboration
    • Philips Hue Personal Wireless Lighting, a smart lighting system for customizable and wireless home illumination
    • Ray-Ban Meta Smart glasses, a pair of smart glasses designed for capturing photos and videos with integrated connectivity and social features
    • Razer Synapse, a unified configuration software enabling hardware customization for Razer devices
    • Siemens SINEMA Remote Connect, a remote connectivity solution for monitoring and managing industrial networks and devices securely
    • Sony PlayStation 4, a gaming console developed by Sony that offers a wide range of games and multimedia entertainment features
    • Sony Virtual Webcam Driver for Remote Camera, a software driver that enables the use of Sony cameras as virtual webcams for video conferencing and streaming

    Operating Systems

    • Apple iOS and macOS, a family of operating systems developed by Apple, including iOS for mobile devices and macOS for desktop computers
    • Google Fuchsia, an open-source operating system developed by Google, designed to be secure, updatable, and adaptable across various devices
    • SerenityOS, an open-source operating system that aims to provide a simple and beautiful user experience with a focus on simplicity and elegance
    • Yocto, a Linux-based build system for creating custom operating systems and software distributions, tailored for embedded devices and IoT applications

    Development Tools and IDEs

    • Accentize SpectralBalance, an adaptive speech analysis tool designed to enhance audio quality by optimizing frequency balance in recordings
    • Arm Compiler for Linux, a software development toolchain for compiling and optimizing applications on Arm-based Linux systems
    • BBEdit, a professional text and code editor for macOS
    • CoderPad, a collaborative coding platform that enables real-time code interviews and assessments for developers; the library is included in every CoderPad instance and can be accessed with a simple #include "json.hpp"
    • Compiler Explorer, a web-based tool that allows users to write, compile, and visualize the assembly output of code in various programming languages; the library is readily available and accessible with the directive #include <nlohmann/json.hpp>.
    • GitHub CodeQL, a code analysis tool used for identifying security vulnerabilities and bugs in software through semantic queries
    • Hex-Rays, a reverse engineering toolset for analyzing and decompiling binaries, primarily used for security research and vulnerability analysis
    • ImHex, a hex editor designed for reverse engineering, providing advanced features for data analysis and manipulation
    • Intel GPA Framework, a suite of cross-platform tools for capturing, analyzing, and optimizing graphics applications across different APIs
    • Intopix, a provider of advanced image processing and compression solutions used in software development and AV workflows
    • Java SE, the core Java platform that provides the libraries and runtime needed to build and run general-purpose Java applications
    • MKVToolNix, a set of tools for creating, editing, and inspecting MKV (Matroska) multimedia container files
    • Meta Yoga, a layout engine that facilitates flexible and efficient user interface design across multiple platforms
    • NVIDIA Nsight Compute, a performance analysis tool for CUDA applications that provides detailed insights into GPU performance metrics
    • Notepad++, a free source code editor that supports various programming languages
    • OpenRGB, an open source RGB lighting control that doesn't depend on manufacturer software
    • OpenTelemetry C++, a library for collecting and exporting observability data in C++, enabling developers to implement distributed tracing and metrics in their application
    • Qt Creator, an IDE for developing applications using the Qt application framework
    • Scanbot SDK, a software development kit (SDK) that provides tools for integrating advanced document scanning and barcode scanning capabilities into applications

    Machine Learning and AI

    • Apple Core ML Tools, a set of tools for converting and configuring machine learning models for deployment in Apple's Core ML framework
    • Avular Mobile Robotics, a platform for developing and deploying mobile robotics solutions
    • Google gemma.cpp, a lightweight C++ inference engine designed for running AI models from the Gemma family
    • llama.cpp, a C++ library designed for efficient inference of large language models (LLMs), enabling streamlined integration into applications
    • MLX, an array framework for machine learning on Apple Silicon
    • Mozilla llamafile, a tool designed for distributing and executing large language models (LLMs) efficiently using a single file format
    • NVIDIA ACE, a suite of real-time AI solutions designed for the development of interactive avatars and digital human applications, enabling scalable and sophisticated user interactions
    • Peer, a platform offering personalized AI assistants for interactive learning and creative collaboration
    • stable-diffusion.cpp, a C++ implementation of the Stable Diffusion image generation model
    • TanvasTouch, a software development kit (SDK) that enables developers to create tactile experiences on touchscreens, allowing users to feel textures and physical sensations in a digital environment
    • TensorFlow, a machine learning framework that facilitates the development and training of models, supporting data serialization and efficient data exchange between components

    Scientific Research and Analysis

    • BLACK, a bounded linear temporal logic (LTL) satisfiability checker
    • CERN Atlas Athena, a software framework used in the ATLAS experiment at the Large Hadron Collider (LHC) for performance monitoring
    • ICU, the International Components for Unicode, a mature library for software globalization and multilingual support
    • KAMERA, a platform for synchronized data collection and real-time deep learning to map marine species like polar bears and seals, aiding Arctic ecosystem research
    • KiCad, a free and open-source software suite for electronic design automation
    • Maple, a symbolic and numeric computing environment for advanced mathematical modeling and analysis
    • MeVisLab, a software framework for medical image processing and visualization.
    • OpenPMD API, a versatile programming interface for accessing and managing scientific data, designed to facilitate the efficient storage, retrieval, and sharing of simulation data across various applications and platforms
    • ParaView, an open-source tool for large-scale data visualization and analysis across various scientific domains
    • QGIS, a free and open-source geographic information system (GIS) application that allows users to create, edit, visualize, and analyze geospatial data across a variety of formats
    • VTK, a software library for 3D computer graphics, image processing, and visualization
    • VolView, a lightweight application for interactive visualization and analysis of 3D medical imaging data.

    Business and Productivity Software

    • ArcGIS PRO, a desktop geographic information system (GIS) application developed by Esri for mapping and spatial analysis
    • Autodesk Desktop, a software platform developed by Autodesk for creating and managing desktop applications and services
    • Check Point, a cybersecurity company specializing in threat prevention and network security solutions, offering a range of products designed to protect enterprises from cyber threats and ensure data integrity
    • Microsoft Office for Mac, a suite of productivity applications developed by Microsoft for macOS, including tools for word processing, spreadsheets, and presentations
    • Microsoft Teams, a team collaboration application offering workspace chat and video conferencing, file storage, and integration of proprietary and third-party applications and services
    • Nexthink Infinity, a digital employee experience management platform for monitoring and improving IT performance
    • Sophos Connect Client, a secure VPN client from Sophos that allows remote users to connect to their corporate network, ensuring secure access to resources and data
    • Stonebranch, a cloud-based cybersecurity solution that integrates backup, disaster recovery, and cybersecurity features to protect data and ensure business continuity for organizations
    • Tablecruncher, a data analysis tool that allows users to import, analyze, and visualize spreadsheet data, offering interactive features for better insights and decision-making
    • magicplan, a mobile application for creating floor plans and interior designs using augmented reality

    Databases and Big Data

    • ADIOS2, a data management framework designed for high-performance input and output operations
    • Cribl Stream, a real-time data processing platform that enables organizations to collect, route, and transform observability data, enhancing visibility and insights into their systems
    • DB Browser for SQLite, a visual open-source tool for creating, designing, and editing SQLite database files
    • MySQL Connector/C++, a C++ library for connecting and interacting with MySQL databases
    • MySQL NDB Cluster, a distributed database system that provides high availability and scalability for MySQL databases
    • MySQL Shell, an advanced client and code editor for interacting with MySQL servers, supporting SQL, Python, and JavaScript
    • PrestoDB, a distributed SQL query engine designed for large-scale data analytics, originally developed by Facebook
    • ROOT Data Analysis Framework, an open-source data analysis framework widely used in high-energy physics and other fields for data processing and visualization
    • WiredTiger, a high-performance storage engine for databases, offering support for compression, concurrency, and checkpointing

    Simulation and Modeling

    • Arcturus HoloSuite, a software toolset for capturing, editing, and streaming volumetric video, featuring advanced compression technologies for high-quality 3D content creation
    • azul, a fast and efficient 3D city model viewer designed for visualizing urban environments and spatial data
    • Blender, a free and open-source 3D creation suite for modeling, animation, rendering, and more
    • cpplot, a library for creating interactive graphs and charts in C++, which can be viewed in web browsers
    • Foundry Nuke, a powerful node-based digital compositing and visual effects application used in film and television post-production
    • GAMS, a high-performance mathematical modeling system for optimization and decision support
    • Kitware SMTK, a software toolkit for managing simulation models and workflows in scientific and engineering applications
    • M-Star, a computational fluid dynamics software for simulating and analyzing fluid flow
    • MapleSim CAD Toolbox, a software extension for MapleSim that integrates CAD models, allowing users to import, manipulate, and analyze 3D CAD data within the MapleSim environment for enhanced modeling and simulation
    • NVIDIA Omniverse, a platform for 3D content creation and collaboration that enables real-time simulations and interactive experiences across various industries
    • Pixar Renderman, a photorealistic 3D rendering software developed by Pixar, widely used in the film industry for creating high-quality visual effects and animations
    • ROS - Robot Operating System, a set of software libraries and tools that assist in developing robot applications
    • UBS, a multinational financial services and banking company

    Enterprise and Cloud Applications

    • Acronis Cyber Protect Cloud, an all-in-one data protection solution that combines backup, disaster recovery, and cybersecurity to safeguard business data from threats like ransomware
    • Baereos, a backup solution that provides data protection and recovery options for various environments, including physical and virtual systems
    • Bitdefender Home Scanner, a tool from Bitdefender that scans devices for malware and security threats, providing a safeguard against potential online dangers
    • Citrix Provisioning, a solution that streamlines the delivery of virtual desktops and applications by allowing administrators to manage and provision resources efficiently across multiple environments
    • Citrix Virtual Apps and Desktops, a solution from Citrix that delivers virtual apps and desktops
    • Cyberarc, a security solution that specializes in privileged access management, enabling organizations to control and monitor access to critical systems and data, thereby enhancing overall cybersecurity posture
    • Egnyte Desktop, a secure cloud storage solution designed for businesses, enabling file sharing, collaboration, and data management across teams while ensuring compliance and data protection
    • Elster, a digital platform developed by German tax authorities for secure and efficient electronic tax filing and management using secunet protect4use
    • Ethereum Solidity, a high-level, object-oriented programming language designed for implementing smart contracts on the Ethereum platform
    • Inciga, a monitoring tool for IT infrastructure, designed to provide insights into system performance and availability through customizable dashboards and alerts
    • Intel Accelerator Management Daemon for VMware ESXi, a management tool designed for monitoring and controlling Intel hardware accelerators within VMware ESXi environments, optimizing performance and resource allocation
    • Juniper Identity Management Service
    • Microsoft Azure IoT SDK, a collection of tools and libraries to help developers connect, build, and deploy Internet of Things (IoT) solutions on the Azure cloud platform
    • Microsoft WinGet, a command-line utility included in the Windows Package Manager
    • plexusAV, a high-performance AV-over-IP transceiver device capable of video encoding and decoding using the IPMX standard
    • Pointr, a platform for indoor positioning and navigation solutions, offering tools and SDKs for developers to create location-based applications
    • secunet protect4use, a secure, passwordless multifactor authentication solution that transforms smartphones into digital keyrings, ensuring high security for online services and digital identities
    • Sencore MRD 7000, a professional multi-channel receiver and decoder supporting UHD and HD stream decoding
    \ No newline at end of file + Customers - JSON for Modern C++

    Customers

    The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but the result of an internet search. If you know further customers of the library, please let me know.

    Space Exploration

    • Peregrine Lunar Lander Flight 01 - The library was used for payload management in the Peregrine Moon Lander, developed by Astrobotic Technology and launched as part of NASA's Commercial Lunar Payload Services (CLPS) program. After six days in orbit, the spacecraft was intentionally redirected into Earth's atmosphere, where it burned up over the Pacific Ocean on January 18, 2024.

    Automotive

    Gaming and Entertainment

    • Assassin's Creed: Mirage, a stealth-action game set in the Middle East, focusing on the journey of a young assassin with classic parkour and stealth mechanics
    • Chasm: The Rift, a first-person shooter blending horror and adventure, where players navigate dark realms and battle monsters
    • College Football 25, a college football simulation game featuring gameplay that mimics real-life college teams and competitions
    • Concepts, a digital sketching app designed for creative professionals, offering flexible drawing tools for illustration, design, and brainstorming
    • Depthkit, a tool for creating and capturing volumetric video, enabling immersive 3D experiences and interactive content
    • IMG.LY, a platform offering creative tools and SDKs for integrating advanced image and video editing in applications
    • LOOT, a tool for optimizing the load order of game plugins, commonly used in The Elder Scrolls and Fallout series
    • Madden NFL 25, a sports simulation game capturing the excitement of American football with realistic gameplay and team management features
    • Marne, an unofficial private server platform for hosting custom Battlefield 1 game experiences
    • Minecraft, a popular sandbox video game
    • NHL 22, a hockey simulation game offering realistic gameplay, team management, and various modes to enhance the hockey experience
    • Pixelpart, a 2D animation and video compositing software that allows users to create animated graphics and visual effects with a focus on simplicity and ease of use
    • Razer Cortex, a gaming performance optimizer and system booster designed to enhance the gaming experience
    • Red Dead Redemption II, an open-world action-adventure game following an outlaw's story in the late 1800s, emphasizing deep storytelling and immersive gameplay
    • Snapchat, a multimedia messaging and augmented reality app for communication and entertainment
    • Tactics Ogre: Reborn, a tactical role-playing game featuring strategic battles and deep storytelling elements
    • Throne and Liberty, an MMORPG that offers an expansive fantasy world with dynamic gameplay and immersive storytelling
    • Unity Vivox, a communication service that enables voice and text chat functionality in multiplayer games developed with Unity
    • Zool: Redimensioned, a modern reimagining of the classic platformer featuring fast-paced gameplay and vibrant environments
    • immersivetech, a technology company focused on immersive experiences, providing tools and solutions for virtual and augmented reality applications

    Consumer Electronics

    • Audinate, a provider of networked audio solutions specializing in Dante technology, which facilitates high-quality digital audio transport over IP networks
    • Canon CanoScan LIDE, a series of flatbed scanners offering high-resolution image scanning for home and office use
    • Canon PIXMA Printers, a line of all-in-one inkjet printers known for high-quality printing and wireless connectivity
    • Cisco Webex Desk Camera, a video camera designed for professional-quality video conferencing and remote collaboration
    • Philips Hue Personal Wireless Lighting, a smart lighting system for customizable and wireless home illumination
    • Ray-Ban Meta Smart glasses, a pair of smart glasses designed for capturing photos and videos with integrated connectivity and social features
    • Razer Synapse, a unified configuration software enabling hardware customization for Razer devices
    • Siemens SINEMA Remote Connect, a remote connectivity solution for monitoring and managing industrial networks and devices securely
    • Sony PlayStation 4, a gaming console developed by Sony that offers a wide range of games and multimedia entertainment features
    • Sony Virtual Webcam Driver for Remote Camera, a software driver that enables the use of Sony cameras as virtual webcams for video conferencing and streaming

    Operating Systems

    • Apple iOS and macOS, a family of operating systems developed by Apple, including iOS for mobile devices and macOS for desktop computers
    • Google Fuchsia, an open-source operating system developed by Google, designed to be secure, updatable, and adaptable across various devices
    • SerenityOS, an open-source operating system that aims to provide a simple and beautiful user experience with a focus on simplicity and elegance
    • Yocto, a Linux-based build system for creating custom operating systems and software distributions, tailored for embedded devices and IoT applications

    Development Tools and IDEs

    • Accentize SpectralBalance, an adaptive speech analysis tool designed to enhance audio quality by optimizing frequency balance in recordings
    • Arm Compiler for Linux, a software development toolchain for compiling and optimizing applications on Arm-based Linux systems
    • BBEdit, a professional text and code editor for macOS
    • CoderPad, a collaborative coding platform that enables real-time code interviews and assessments for developers; the library is included in every CoderPad instance and can be accessed with a simple #include "json.hpp"
    • Compiler Explorer, a web-based tool that allows users to write, compile, and visualize the assembly output of code in various programming languages; the library is readily available and accessible with the directive #include <nlohmann/json.hpp>.
    • GitHub CodeQL, a code analysis tool used for identifying security vulnerabilities and bugs in software through semantic queries
    • Hex-Rays, a reverse engineering toolset for analyzing and decompiling binaries, primarily used for security research and vulnerability analysis
    • ImHex, a hex editor designed for reverse engineering, providing advanced features for data analysis and manipulation
    • Intel GPA Framework, a suite of cross-platform tools for capturing, analyzing, and optimizing graphics applications across different APIs
    • Intopix, a provider of advanced image processing and compression solutions used in software development and AV workflows
    • Java SE, the core Java platform that provides the libraries and runtime needed to build and run general-purpose Java applications
    • MKVToolNix, a set of tools for creating, editing, and inspecting MKV (Matroska) multimedia container files
    • Meta Yoga, a layout engine that facilitates flexible and efficient user interface design across multiple platforms
    • NVIDIA Nsight Compute, a performance analysis tool for CUDA applications that provides detailed insights into GPU performance metrics
    • Notepad++, a free source code editor that supports various programming languages
    • OpenRGB, an open source RGB lighting control that doesn't depend on manufacturer software
    • OpenTelemetry C++, a library for collecting and exporting observability data in C++, enabling developers to implement distributed tracing and metrics in their application
    • Qt Creator, an IDE for developing applications using the Qt application framework
    • Scanbot SDK, a software development kit (SDK) that provides tools for integrating advanced document scanning and barcode scanning capabilities into applications

    Machine Learning and AI

    • Apple Core ML Tools, a set of tools for converting and configuring machine learning models for deployment in Apple's Core ML framework
    • Avular Mobile Robotics, a platform for developing and deploying mobile robotics solutions
    • Google gemma.cpp, a lightweight C++ inference engine designed for running AI models from the Gemma family
    • llama.cpp, a C++ library designed for efficient inference of large language models (LLMs), enabling streamlined integration into applications
    • MLX, an array framework for machine learning on Apple Silicon
    • Mozilla llamafile, a tool designed for distributing and executing large language models (LLMs) efficiently using a single file format
    • NVIDIA ACE, a suite of real-time AI solutions designed for the development of interactive avatars and digital human applications, enabling scalable and sophisticated user interactions
    • Peer, a platform offering personalized AI assistants for interactive learning and creative collaboration
    • stable-diffusion.cpp, a C++ implementation of the Stable Diffusion image generation model
    • TanvasTouch, a software development kit (SDK) that enables developers to create tactile experiences on touchscreens, allowing users to feel textures and physical sensations in a digital environment
    • TensorFlow, a machine learning framework that facilitates the development and training of models, supporting data serialization and efficient data exchange between components

    Scientific Research and Analysis

    • BLACK, a bounded linear temporal logic (LTL) satisfiability checker
    • CERN Atlas Athena, a software framework used in the ATLAS experiment at the Large Hadron Collider (LHC) for performance monitoring
    • ICU, the International Components for Unicode, a mature library for software globalization and multilingual support
    • KAMERA, a platform for synchronized data collection and real-time deep learning to map marine species like polar bears and seals, aiding Arctic ecosystem research
    • KiCad, a free and open-source software suite for electronic design automation
    • Maple, a symbolic and numeric computing environment for advanced mathematical modeling and analysis
    • MeVisLab, a software framework for medical image processing and visualization.
    • OpenPMD API, a versatile programming interface for accessing and managing scientific data, designed to facilitate the efficient storage, retrieval, and sharing of simulation data across various applications and platforms
    • ParaView, an open-source tool for large-scale data visualization and analysis across various scientific domains
    • QGIS, a free and open-source geographic information system (GIS) application that allows users to create, edit, visualize, and analyze geospatial data across a variety of formats
    • VTK, a software library for 3D computer graphics, image processing, and visualization
    • VolView, a lightweight application for interactive visualization and analysis of 3D medical imaging data.

    Business and Productivity Software

    • ArcGIS PRO, a desktop geographic information system (GIS) application developed by Esri for mapping and spatial analysis
    • Autodesk Desktop, a software platform developed by Autodesk for creating and managing desktop applications and services
    • Check Point, a cybersecurity company specializing in threat prevention and network security solutions, offering a range of products designed to protect enterprises from cyber threats and ensure data integrity
    • Microsoft Office for Mac, a suite of productivity applications developed by Microsoft for macOS, including tools for word processing, spreadsheets, and presentations
    • Microsoft Teams, a team collaboration application offering workspace chat and video conferencing, file storage, and integration of proprietary and third-party applications and services
    • Nexthink Infinity, a digital employee experience management platform for monitoring and improving IT performance
    • Sophos Connect Client, a secure VPN client from Sophos that allows remote users to connect to their corporate network, ensuring secure access to resources and data
    • Stonebranch, a cloud-based cybersecurity solution that integrates backup, disaster recovery, and cybersecurity features to protect data and ensure business continuity for organizations
    • Tablecruncher, a data analysis tool that allows users to import, analyze, and visualize spreadsheet data, offering interactive features for better insights and decision-making
    • magicplan, a mobile application for creating floor plans and interior designs using augmented reality

    Databases and Big Data

    • ADIOS2, a data management framework designed for high-performance input and output operations
    • Cribl Stream, a real-time data processing platform that enables organizations to collect, route, and transform observability data, enhancing visibility and insights into their systems
    • DB Browser for SQLite, a visual open-source tool for creating, designing, and editing SQLite database files
    • MySQL Connector/C++, a C++ library for connecting and interacting with MySQL databases
    • MySQL NDB Cluster, a distributed database system that provides high availability and scalability for MySQL databases
    • MySQL Shell, an advanced client and code editor for interacting with MySQL servers, supporting SQL, Python, and JavaScript
    • PrestoDB, a distributed SQL query engine designed for large-scale data analytics, originally developed by Facebook
    • ROOT Data Analysis Framework, an open-source data analysis framework widely used in high-energy physics and other fields for data processing and visualization
    • WiredTiger, a high-performance storage engine for databases, offering support for compression, concurrency, and checkpointing

    Simulation and Modeling

    • Arcturus HoloSuite, a software toolset for capturing, editing, and streaming volumetric video, featuring advanced compression technologies for high-quality 3D content creation
    • azul, a fast and efficient 3D city model viewer designed for visualizing urban environments and spatial data
    • Blender, a free and open-source 3D creation suite for modeling, animation, rendering, and more
    • cpplot, a library for creating interactive graphs and charts in C++, which can be viewed in web browsers
    • Foundry Nuke, a powerful node-based digital compositing and visual effects application used in film and television post-production
    • GAMS, a high-performance mathematical modeling system for optimization and decision support
    • Kitware SMTK, a software toolkit for managing simulation models and workflows in scientific and engineering applications
    • M-Star, a computational fluid dynamics software for simulating and analyzing fluid flow
    • MapleSim CAD Toolbox, a software extension for MapleSim that integrates CAD models, allowing users to import, manipulate, and analyze 3D CAD data within the MapleSim environment for enhanced modeling and simulation
    • NVIDIA Omniverse, a platform for 3D content creation and collaboration that enables real-time simulations and interactive experiences across various industries
    • Pixar Renderman, a photorealistic 3D rendering software developed by Pixar, widely used in the film industry for creating high-quality visual effects and animations
    • ROS - Robot Operating System, a set of software libraries and tools that assist in developing robot applications
    • UBS, a multinational financial services and banking company

    Enterprise and Cloud Applications

    • Acronis Cyber Protect Cloud, an all-in-one data protection solution that combines backup, disaster recovery, and cybersecurity to safeguard business data from threats like ransomware
    • Baereos, a backup solution that provides data protection and recovery options for various environments, including physical and virtual systems
    • Bitdefender Home Scanner, a tool from Bitdefender that scans devices for malware and security threats, providing a safeguard against potential online dangers
    • Citrix Provisioning, a solution that streamlines the delivery of virtual desktops and applications by allowing administrators to manage and provision resources efficiently across multiple environments
    • Citrix Virtual Apps and Desktops, a solution from Citrix that delivers virtual apps and desktops
    • Cyberarc, a security solution that specializes in privileged access management, enabling organizations to control and monitor access to critical systems and data, thereby enhancing overall cybersecurity posture
    • Egnyte Desktop, a secure cloud storage solution designed for businesses, enabling file sharing, collaboration, and data management across teams while ensuring compliance and data protection
    • Elster, a digital platform developed by German tax authorities for secure and efficient electronic tax filing and management using secunet protect4use
    • Ethereum Solidity, a high-level, object-oriented programming language designed for implementing smart contracts on the Ethereum platform
    • Inciga, a monitoring tool for IT infrastructure, designed to provide insights into system performance and availability through customizable dashboards and alerts
    • Intel Accelerator Management Daemon for VMware ESXi, a management tool designed for monitoring and controlling Intel hardware accelerators within VMware ESXi environments, optimizing performance and resource allocation
    • Juniper Identity Management Service
    • Microsoft Azure IoT SDK, a collection of tools and libraries to help developers connect, build, and deploy Internet of Things (IoT) solutions on the Azure cloud platform
    • Microsoft WinGet, a command-line utility included in the Windows Package Manager
    • plexusAV, a high-performance AV-over-IP transceiver device capable of video encoding and decoding using the IPMX standard
    • Pointr, a platform for indoor positioning and navigation solutions, offering tools and SDKs for developers to create location-based applications
    • secunet protect4use, a secure, passwordless multifactor authentication solution that transforms smartphones into digital keyrings, ensuring high security for online services and digital identities
    • Sencore MRD 7000, a professional multi-channel receiver and decoder supporting UHD and HD stream decoding
    \ No newline at end of file diff --git a/home/customers/index.md b/home/customers/index.md new file mode 100644 index 000000000..c4c8e30da --- /dev/null +++ b/home/customers/index.md @@ -0,0 +1,175 @@ +# Customers + +The library is used in multiple projects, applications, operating systems, etc. The list below is not exhaustive, but the result of an internet search. If you know further customers of the library, [please let me know](mailto:mail@nlohmann.me). + +## Space Exploration + +- [**Peregrine Lunar Lander Flight 01**](https://en.wikipedia.org/wiki/Peregrine_Mission_One) - The library was used for payload management in the **Peregrine Moon Lander**, developed by **Astrobotic Technology** and launched as part of NASA's **Commercial Lunar Payload Services (CLPS)** program. After six days in orbit, the spacecraft was intentionally redirected into Earth's atmosphere, where it burned up over the Pacific Ocean on **January 18, 2024**. + +## Automotive + +- [**Alexa Auto SDK**](https://github.com/alexa/alexa-auto-sdk), a software development kit enabling the integration of Alexa into automotive systems +- [**Apollo**](https://github.com/ApolloAuto/apollo), a framework for building autonomous driving systems +- [**Automotive Grade Linux (AGL)**](https://download.automotivelinux.org/AGL/release/jellyfish/latest/qemux86-64/deploy/licenses/nlohmann-json/), a collaborative open-source platform for automotive software development +- [**Genesis Motor** (infotainment)](http://webmanual.genesis.com/ccIC/AVNT/JW/KOR/English/reference010.html), a luxury automotive brand +- [**Hyundai** (infotainment)](https://www.hyundai.com/wsvc/ww/download.file.do?id=/content/hyundai/ww/data/opensource/data/GN7-2022/licenseCode/info), a global automotive brand +- [**Kia** (infotainment)](http://webmanual.kia.com/PREM_GEN6/AVNT/RJPE/KOR/Korean/reference010.html), a global automotive brand +- [**Mercedes-Benz Operating System (MB.OS)**](https://group.mercedes-benz.com/careers/about-us/mercedes-benz-operating-system/), a core component of the vehicle software ecosystem from Mercedes-Benz +- [**Rivian** (infotainment)](https://assets.ctfassets.net/2md5qhoeajym/3cwyo4eoufk4yingUwusFt/ded2c47da620fdfc99c88c7156d2c1d8/In-Vehicle_OSS_Attribution_2024__11-24_.pdf), an electric vehicle manufacturer +- [**Suzuki** (infotainment)](https://www.globalsuzuki.com/motorcycle/ipc/oss/oss_48KA_00.pdf), a global automotive and motorcycle manufacturer + +## Gaming and Entertainment + +- [**Assassin's Creed: Mirage**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a stealth-action game set in the Middle East, focusing on the journey of a young assassin with classic parkour and stealth mechanics +- [**Chasm: The Rift**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a first-person shooter blending horror and adventure, where players navigate dark realms and battle monsters +- [**College Football 25**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a college football simulation game featuring gameplay that mimics real-life college teams and competitions +- [**Concepts**](https://concepts.app/en/licenses), a digital sketching app designed for creative professionals, offering flexible drawing tools for illustration, design, and brainstorming +- [**Depthkit**](https://www.depthkit.tv/third-party-licenses), a tool for creating and capturing volumetric video, enabling immersive 3D experiences and interactive content +- [**IMG.LY**](https://img.ly/acknowledgements), a platform offering creative tools and SDKs for integrating advanced image and video editing in applications +- [**LOOT**](https://loot.readthedocs.io/_/downloads/en/0.13.0/pdf/), a tool for optimizing the load order of game plugins, commonly used in The Elder Scrolls and Fallout series +- [**Madden NFL 25**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a sports simulation game capturing the excitement of American football with realistic gameplay and team management features +- [**Marne**](https://marne.io/licenses), an unofficial private server platform for hosting custom Battlefield 1 game experiences +- [**Minecraft**](https://www.minecraft.net/zh-hant/attribution), a popular sandbox video game +- [**NHL 22**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a hockey simulation game offering realistic gameplay, team management, and various modes to enhance the hockey experience +- [**Pixelpart**](https://pixelpart.net/documentation/book/third-party.html), a 2D animation and video compositing software that allows users to create animated graphics and visual effects with a focus on simplicity and ease of use +- [**Razer Cortex**](https://mysupport.razer.com/app/answers/detail/a_id/14146/~/open-source-software-for-razer-software), a gaming performance optimizer and system booster designed to enhance the gaming experience +- [**Red Dead Redemption II**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), an open-world action-adventure game following an outlaw's story in the late 1800s, emphasizing deep storytelling and immersive gameplay +- [**Snapchat**](https://www.snap.com/terms/license-android), a multimedia messaging and augmented reality app for communication and entertainment +- [**Tactics Ogre: Reborn**](https://www.square-enix-games.com/en_US/documents/tactics-ogre-reborn-pc-installer-software-and-associated-plug-ins-disclosure), a tactical role-playing game featuring strategic battles and deep storytelling elements +- [**Throne and Liberty**](https://www.amazon.com/gp/help/customer/display.html?nodeId=T7fLNw5oAevCMtJFPj&pop-up=1), an MMORPG that offers an expansive fantasy world with dynamic gameplay and immersive storytelling +- [**Unity Vivox**](https://docs.unity3d.com/Packages/com.unity.services.vivox@15.1/license/Third%20Party%20Notices.html), a communication service that enables voice and text chat functionality in multiplayer games developed with Unity +- [**Zool: Redimensioned**](https://www.mobygames.com/person/1195889/niels-lohmann/credits/), a modern reimagining of the classic platformer featuring fast-paced gameplay and vibrant environments +- [**immersivetech**](https://immersitech.io/open-source-third-party-software/), a technology company focused on immersive experiences, providing tools and solutions for virtual and augmented reality applications + +## Consumer Electronics + +- [**Audinate**](https://www.audinate.com/legal/software-licensing/dante-av-h-open-source-licenses/), a provider of networked audio solutions specializing in Dante technology, which facilitates high-quality digital audio transport over IP networks +- [**Canon CanoScan LIDE**](https://carolburo.com/wp-content/uploads/2024/06/LiDE400_OnlineManual_Win_FR_V02.pdf), a series of flatbed scanners offering high-resolution image scanning for home and office use +- [**Canon PIXMA Printers**](https://www.mediaexpert.pl/products/files/73/7338196/Instrukcja-obslugi-CANON-Pixma-TS7450i.pdf), a line of all-in-one inkjet printers known for high-quality printing and wireless connectivity +- [**Cisco Webex Desk Camera**](https://www.cisco.com/c/dam/en_us/about/doing_business/open_source/docs/CiscoWebexDeskCamera-23-1622100417.pdf), a video camera designed for professional-quality video conferencing and remote collaboration +- [**Philips Hue Personal Wireless Lighting**](http://2ak5ape.257.cz/), a smart lighting system for customizable and wireless home illumination +- [**Ray-Ban Meta Smart glasses**](https://www.meta.com/de/en/legal/smart-glasses/third-party-notices-android/03/), a pair of smart glasses designed for capturing photos and videos with integrated connectivity and social features +- [**Razer Synapse**](https://mysupport.razer.com/app/answers/detail/a_id/14146/~/open-source-software-for-razer-software), a unified configuration software enabling hardware customization for Razer devices +- [**Siemens SINEMA Remote Connect**](https://cache.industry.siemens.com/dl/files/790/109793790/att_1054961/v2/OSS_SINEMA-RC_86.pdf), a remote connectivity solution for monitoring and managing industrial networks and devices securely +- [**Sony PlayStation 4**](https://doc.dl.playstation.net/doc/ps4-oss/index.html), a gaming console developed by Sony that offers a wide range of games and multimedia entertainment features +- [**Sony Virtual Webcam Driver for Remote Camera**](https://helpguide.sony.net/rc/vwd/v1/zh-cn/print.pdf), a software driver that enables the use of Sony cameras as virtual webcams for video conferencing and streaming + +## Operating Systems + +- [**Apple iOS and macOS**](https://www.apple.com/macos), a family of operating systems developed by Apple, including iOS for mobile devices and macOS for desktop computers +- [**Google Fuchsia**](https://fuchsia.googlesource.com/third_party/json/), an open-source operating system developed by Google, designed to be secure, updatable, and adaptable across various devices +- [**SerenityOS**](https://github.com/SerenityOS/serenity), an open-source operating system that aims to provide a simple and beautiful user experience with a focus on simplicity and elegance +- [**Yocto**](http://ftp.emacinc.com/openembedded-sw/kirkstone-icop-5.15-kirkstone-6.0/archive-2024-10/pn8m-090t-ppc/licenses/nlohmann-json/), a Linux-based build system for creating custom operating systems and software distributions, tailored for embedded devices and IoT applications + +## Development Tools and IDEs + +- [**Accentize SpectralBalance**](https://www.accentize.com/products/SpectralBalanceManual.pdf), an adaptive speech analysis tool designed to enhance audio quality by optimizing frequency balance in recordings +- [**Arm Compiler for Linux**](https://documentation-service.arm.com/static/66558e9d876c8d213b7843e4), a software development toolchain for compiling and optimizing applications on Arm-based Linux systems +- [**BBEdit**](https://s3.amazonaws.com/BBSW-download/BBEdit_15.1.2_User_Manual.pdf), a professional text and code editor for macOS +- [**CoderPad**](https://coderpad.io), a collaborative coding platform that enables real-time code interviews and assessments for developers; the library is included in every CoderPad instance and can be accessed with a simple `#include "json.hpp"` +- [**Compiler Explorer**](https://godbolt.org), a web-based tool that allows users to write, compile, and visualize the assembly output of code in various programming languages; the library is readily available and accessible with the directive `#include `. +- [**GitHub CodeQL**](https://github.com/github/codeql), a code analysis tool used for identifying security vulnerabilities and bugs in software through semantic queries +- [**Hex-Rays**](https://docs.hex-rays.com/user-guide/user-interface/licenses), a reverse engineering toolset for analyzing and decompiling binaries, primarily used for security research and vulnerability analysis +- [**ImHex**](https://github.com/WerWolv/ImHex), a hex editor designed for reverse engineering, providing advanced features for data analysis and manipulation +- [**Intel GPA Framework**](https://intel.github.io/gpasdk-doc/src/licenses.html), a suite of cross-platform tools for capturing, analyzing, and optimizing graphics applications across different APIs +- [**Intopix**](https://www.intopix.com/software-licensing), a provider of advanced image processing and compression solutions used in software development and AV workflows +- [**Java SE**](https://www.oracle.com/a/tech/docs/jdk8-lium.pdf), the core Java platform that provides the libraries and runtime needed to build and run general-purpose Java applications +- [**MKVToolNix**](https://mkvtoolnix.download/doc/README.md), a set of tools for creating, editing, and inspecting MKV (Matroska) multimedia container files +- [**Meta Yoga**](https://github.com/facebook/yoga), a layout engine that facilitates flexible and efficient user interface design across multiple platforms +- [**NVIDIA Nsight Compute**](https://docs.nvidia.com/nsight-compute/2022.2/pdf/CopyrightAndLicenses.pdf), a performance analysis tool for CUDA applications that provides detailed insights into GPU performance metrics +- [**Notepad++**](https://github.com/notepad-plus-plus/notepad-plus-plus), a free source code editor that supports various programming languages +- [**OpenRGB**](https://gitlab.com/CalcProgrammer1/OpenRGB), an open source RGB lighting control that doesn't depend on manufacturer software +- [**OpenTelemetry C++**](https://github.com/open-telemetry/opentelemetry-cpp), a library for collecting and exporting observability data in C++, enabling developers to implement distributed tracing and metrics in their application +- [**Qt Creator**](https://doc.qt.io/qtcreator/qtcreator-attribution-json-nlohmann.html), an IDE for developing applications using the Qt application framework +- [**Scanbot SDK**](https://docs.scanbot.io/barcode-scanner-sdk/web/third-party-libraries/), a software development kit (SDK) that provides tools for integrating advanced document scanning and barcode scanning capabilities into applications + +## Machine Learning and AI + +- [**Apple Core ML Tools**](https://github.com/apple/coremltools), a set of tools for converting and configuring machine learning models for deployment in Apple's Core ML framework +- [**Avular Mobile Robotics**](https://www.avular.com/licenses/nlohmann-json-3.9.1.txt), a platform for developing and deploying mobile robotics solutions +- [**Google gemma.cpp**](https://github.com/google/gemma.cpp), a lightweight C++ inference engine designed for running AI models from the Gemma family +- [**llama.cpp**](https://github.com/ggerganov/llama.cpp), a C++ library designed for efficient inference of large language models (LLMs), enabling streamlined integration into applications +- [**MLX**](https://github.com/ml-explore/mlx), an array framework for machine learning on Apple Silicon +- [**Mozilla llamafile**](https://github.com/Mozilla-Ocho/llamafile), a tool designed for distributing and executing large language models (LLMs) efficiently using a single file format +- [**NVIDIA ACE**](https://docs.nvidia.com/ace/latest/index.html), a suite of real-time AI solutions designed for the development of interactive avatars and digital human applications, enabling scalable and sophisticated user interactions +- [**Peer**](https://support.peer.inc/hc/en-us/articles/17261335054235-Licenses), a platform offering personalized AI assistants for interactive learning and creative collaboration +- [**stable-diffusion.cpp**](https://github.com/leejet/stable-diffusion.cpp), a C++ implementation of the Stable Diffusion image generation model +- [**TanvasTouch**](https://tanvas.co/tanvastouch-sdk-third-party-acknowledgments), a software development kit (SDK) that enables developers to create tactile experiences on touchscreens, allowing users to feel textures and physical sensations in a digital environment +- [**TensorFlow**](https://github.com/tensorflow/tensorflow), a machine learning framework that facilitates the development and training of models, supporting data serialization and efficient data exchange between components + +## Scientific Research and Analysis + +- [**BLACK**](https://www.black-sat.org/en/stable/installation/linux.html), a bounded linear temporal logic (LTL) satisfiability checker +- [**CERN Atlas Athena**](https://gitlab.cern.ch/atlas/athena/-/blob/main/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonMTSvc.h), a software framework used in the ATLAS experiment at the Large Hadron Collider (LHC) for performance monitoring +- [**ICU**](https://github.com/unicode-org/icu), the International Components for Unicode, a mature library for software globalization and multilingual support +- [**KAMERA**](https://github.com/Kitware/kamera), a platform for synchronized data collection and real-time deep learning to map marine species like polar bears and seals, aiding Arctic ecosystem research +- [**KiCad**](https://gitlab.com/kicad/code/kicad/-/tree/master/thirdparty/nlohmann_json), a free and open-source software suite for electronic design automation +- [**Maple**](https://www.maplesoft.com/support/help/Maple/view.aspx?path=copyright), a symbolic and numeric computing environment for advanced mathematical modeling and analysis +- [**MeVisLab**](https://mevislabdownloads.mevis.de/docs/current/MeVis/ThirdParty/Documentation/Publish/ThirdPartyReference/index.html), a software framework for medical image processing and visualization. +- [**OpenPMD API**](https://openpmd-api.readthedocs.io/en/0.8.0-alpha/backends/json.html), a versatile programming interface for accessing and managing scientific data, designed to facilitate the efficient storage, retrieval, and sharing of simulation data across various applications and platforms +- [**ParaView**](https://github.com/Kitware/ParaView), an open-source tool for large-scale data visualization and analysis across various scientific domains +- [**QGIS**](https://gitlab.b-data.ch/qgis/qgis/-/blob/backport-57658-to-release-3_34/external/nlohmann/json.hpp), a free and open-source geographic information system (GIS) application that allows users to create, edit, visualize, and analyze geospatial data across a variety of formats +- [**VTK**](https://github.com/Kitware/VTK), a software library for 3D computer graphics, image processing, and visualization +- [**VolView**](https://github.com/Kitware/VolView), a lightweight application for interactive visualization and analysis of 3D medical imaging data. + +## Business and Productivity Software + +- [**ArcGIS PRO**](https://www.esri.com/content/dam/esrisites/en-us/media/legal/open-source-acknowledgements/arcgis-pro-2-8-attribution-report.html), a desktop geographic information system (GIS) application developed by Esri for mapping and spatial analysis +- [**Autodesk Desktop**](https://damassets.autodesk.net/content/dam/autodesk/www/Company/legal-notices-trademarks/autodesk-desktop-platform-components/internal-autodesk-components-web-page-2023.pdf), a software platform developed by Autodesk for creating and managing desktop applications and services +- [**Check Point**](https://www.checkpoint.com/about-us/copyright-and-trademarks/), a cybersecurity company specializing in threat prevention and network security solutions, offering a range of products designed to protect enterprises from cyber threats and ensure data integrity +- [**Microsoft Office for Mac**](https://officecdnmac.microsoft.com/pr/legal/mac/OfficeforMacAttributions.html), a suite of productivity applications developed by Microsoft for macOS, including tools for word processing, spreadsheets, and presentations +- [**Microsoft Teams**](https://www.microsoft.com/microsoft-teams/), a team collaboration application offering workspace chat and video conferencing, file storage, and integration of proprietary and third-party applications and services +- [**Nexthink Infinity**](https://docs.nexthink.com/legal/services-terms/experience-open-source-software-licenses/infinity-2022.8-software-licenses), a digital employee experience management platform for monitoring and improving IT performance +- [**Sophos Connect Client**](https://docs.sophos.com/nsg/licenses/SophosConnect/SophosConnectAttribution.html), a secure VPN client from Sophos that allows remote users to connect to their corporate network, ensuring secure access to resources and data +- [**Stonebranch**](https://stonebranchdocs.atlassian.net/wiki/spaces/UA77/pages/799545647/Licenses+for+Third-Party+Libraries), a cloud-based cybersecurity solution that integrates backup, disaster recovery, and cybersecurity features to protect data and ensure business continuity for organizations +- [**Tablecruncher**](https://tablecruncher.com/), a data analysis tool that allows users to import, analyze, and visualize spreadsheet data, offering interactive features for better insights and decision-making +- [**magicplan**](https://help.magicplan.app/acknowledgments), a mobile application for creating floor plans and interior designs using augmented reality + +## Databases and Big Data + +- [**ADIOS2**](https://code.ornl.gov/ecpcitest/adios2/-/tree/pr4285_FFSUpstream/thirdparty/nlohmann_json?ref_type=heads), a data management framework designed for high-performance input and output operations +- [**Cribl Stream**](https://docs.cribl.io/stream/third-party-current-list/), a real-time data processing platform that enables organizations to collect, route, and transform observability data, enhancing visibility and insights into their systems +- [**DB Browser for SQLite**](https://github.com/sqlitebrowser/sqlitebrowser), a visual open-source tool for creating, designing, and editing SQLite database files +- [**MySQL Connector/C++**](https://docs.oracle.com/cd/E17952_01/connector-cpp-9.1-license-com-en/license-opentelemetry-cpp-com.html), a C++ library for connecting and interacting with MySQL databases +- [**MySQL NDB Cluster**](https://downloads.mysql.com/docs/licenses/cluster-9.0-com-en.pdf), a distributed database system that provides high availability and scalability for MySQL databases +- [**MySQL Shell**](https://downloads.mysql.com/docs/licenses/mysql-shell-8.0-gpl-en.pdf), an advanced client and code editor for interacting with MySQL servers, supporting SQL, Python, and JavaScript +- [**PrestoDB**](https://github.com/prestodb/presto), a distributed SQL query engine designed for large-scale data analytics, originally developed by Facebook +- [**ROOT Data Analysis Framework**](https://root.cern/doc/v614/classnlohmann_1_1basic__json.html), an open-source data analysis framework widely used in high-energy physics and other fields for data processing and visualization +- [**WiredTiger**](https://github.com/wiredtiger/wiredtiger), a high-performance storage engine for databases, offering support for compression, concurrency, and checkpointing + +## Simulation and Modeling + +- [**Arcturus HoloSuite**](https://www.datocms-assets.com/104353/1698904597-holosuite-third-party-software-credits-and-attributions-2.pdf), a software toolset for capturing, editing, and streaming volumetric video, featuring advanced compression technologies for high-quality 3D content creation +- [**azul**](https://pure.tudelft.nl/ws/files/85338589/tgis.12673.pdf), a fast and efficient 3D city model viewer designed for visualizing urban environments and spatial data +- [**Blender**](https://projects.blender.org/blender/blender/search?q=nlohmann), a free and open-source 3D creation suite for modeling, animation, rendering, and more +- [**cpplot**](https://cpplot.readthedocs.io/en/latest/library_api/function_eigen_8h_1ac080eac0541014c5892a55e41bf785e6.html), a library for creating interactive graphs and charts in C++, which can be viewed in web browsers +- [**Foundry Nuke**](https://learn.foundry.com/nuke/content/misc/studio_third_party_libraries.html), a powerful node-based digital compositing and visual effects application used in film and television post-production +- [**GAMS**](https://www.gams.com/47/docs/THIRDPARTY.html), a high-performance mathematical modeling system for optimization and decision support +- [**Kitware SMTK**](https://github.com/Kitware/SMTK), a software toolkit for managing simulation models and workflows in scientific and engineering applications +- [**M-Star**](https://docs.mstarcfd.com/3_Licensing/thirdparty-licenses.html), a computational fluid dynamics software for simulating and analyzing fluid flow +- [**MapleSim CAD Toolbox**](https://www.maplesoft.com/support/help/MapleSim/view.aspx?path=CADToolbox/copyright), a software extension for MapleSim that integrates CAD models, allowing users to import, manipulate, and analyze 3D CAD data within the MapleSim environment for enhanced modeling and simulation +- [**NVIDIA Omniverse**](https://docs.omniverse.nvidia.com/composer/latest/common/product-licenses/usd-explorer/usd-explorer-2023.2.0-licenses-manifest.html), a platform for 3D content creation and collaboration that enables real-time simulations and interactive experiences across various industries +- [**Pixar Renderman**](https://rmanwiki-26.pixar.com/space/REN26/19662083/Legal+Notice), a photorealistic 3D rendering software developed by Pixar, widely used in the film industry for creating high-quality visual effects and animations +- [**ROS - Robot Operating System**](http://docs.ros.org/en/noetic/api/behaviortree_cpp/html/json_8hpp_source.html), a set of software libraries and tools that assist in developing robot applications +- [**UBS**](https://www.ubs.com/), a multinational financial services and banking company + +## Enterprise and Cloud Applications + +- [**Acronis Cyber Protect Cloud**](https://care.acronis.com/s/article/59533-Third-party-software-used-in-Acronis-Cyber-Protect-Cloud?language=en_US), an all-in-one data protection solution that combines backup, disaster recovery, and cybersecurity to safeguard business data from threats like ransomware +- [**Baereos**](https://gitlab.tiger-computing.co.uk/packages/bareos/-/blob/tiger/bullseye/third-party/CLI11/examples/json.cpp), a backup solution that provides data protection and recovery options for various environments, including physical and virtual systems +- [**Bitdefender Home Scanner**](https://www.bitdefender.de/site/Main/view/home-scanner-open-source.html), a tool from Bitdefender that scans devices for malware and security threats, providing a safeguard against potential online dangers +- [**Citrix Provisioning**](https://docs.citrix.com/en-us/provisioning/2203-ltsr/downloads/pvs-third-party-notices-2203.pdf), a solution that streamlines the delivery of virtual desktops and applications by allowing administrators to manage and provision resources efficiently across multiple environments +- [**Citrix Virtual Apps and Desktops**](https://docs.citrix.com/en-us/citrix-virtual-apps-desktops/2305/downloads/third-party-notices-apps-and-desktops.pdf), a solution from Citrix that delivers virtual apps and desktops +- [**Cyberarc**](https://docs.cyberark.com/Downloads/Legal/Privileged%20Session%20Manager%20for%20SSH%20Third-Party%20Notices.pdf), a security solution that specializes in privileged access management, enabling organizations to control and monitor access to critical systems and data, thereby enhancing overall cybersecurity posture +- [**Egnyte Desktop**](https://helpdesk.egnyte.com/hc/en-us/articles/360007071732-Third-Party-Software-Acknowledgements), a secure cloud storage solution designed for businesses, enabling file sharing, collaboration, and data management across teams while ensuring compliance and data protection +- [**Elster**](https://www.secunet.com/en/about-us/press/article/elstersecure-bietet-komfortablen-login-ohne-passwort-dank-secunet-protect4use), a digital platform developed by German tax authorities for secure and efficient electronic tax filing and management using secunet protect4use +- [**Ethereum Solidity**](https://github.com/ethereum/solidity), a high-level, object-oriented programming language designed for implementing smart contracts on the Ethereum platform +- [**Inciga**](https://fossies.org/linux/icinga2/third-party/nlohmann_json/json.hpp), a monitoring tool for IT infrastructure, designed to provide insights into system performance and availability through customizable dashboards and alerts +- [**Intel Accelerator Management Daemon for VMware ESXi**](https://downloadmirror.intel.com/772507/THIRD-PARTY.txt), a management tool designed for monitoring and controlling Intel hardware accelerators within VMware ESXi environments, optimizing performance and resource allocation +- [**Juniper Identity Management Service**](https://www.juniper.net/documentation/us/en/software/jims/jims-guide/jims-guide.pdf) +- [**Microsoft Azure IoT SDK**](https://library.e.abb.com/public/2779c5f85f30484192eb3cb3f666a201/IP%20Gateway%20Open%20License%20Declaration_9AKK108467A4095_Rev_C.pdf), a collection of tools and libraries to help developers connect, build, and deploy Internet of Things (IoT) solutions on the Azure cloud platform +- [**Microsoft WinGet**](https://github.com/microsoft/winget-cli), a command-line utility included in the Windows Package Manager +- [**plexusAV**](https://www.sisme.com/media/10994/manual_plexusav-p-avn-4-form8244-c.pdf), a high-performance AV-over-IP transceiver device capable of video encoding and decoding using the IPMX standard +- [**Pointr**](https://docs-dev.pointr.tech/docs/8.x/Developer%20Portal/Open%20Source%20Licenses/), a platform for indoor positioning and navigation solutions, offering tools and SDKs for developers to create location-based applications +- [**secunet protect4use**](https://www.secunet.com/en/about-us/press/article/elstersecure-bietet-komfortablen-login-ohne-passwort-dank-secunet-protect4use), a secure, passwordless multifactor authentication solution that transforms smartphones into digital keyrings, ensuring high security for online services and digital identities +- [**Sencore MRD 7000**](https://www.foccusdigital.com/wp-content/uploads/2025/03/MRD-7000-Manual-8175V.pdf), a professional multi-channel receiver and decoder supporting UHD and HD stream decoding diff --git a/home/design_goals.md b/home/design_goals.md new file mode 100644 index 000000000..0a0f77029 --- /dev/null +++ b/home/design_goals.md @@ -0,0 +1,17 @@ +# Design goals + +There are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals: + +- **Intuitive syntax**. In languages such as Python, JSON feels like a first-class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. + +- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings. + +- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/tests/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289). + +Other aspects were not so important to us: + +- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. + +- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set. + +See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information. diff --git a/home/design_goals/index.html b/home/design_goals/index.html index 141215fb1..66ee758d7 100644 --- a/home/design_goals/index.html +++ b/home/design_goals/index.html @@ -1 +1 @@ - Design goals - JSON for Modern C++

    Design goals

    There are myriads of JSON libraries out there, and each may even have its reason to exist. Our class had these design goals:

    • Intuitive syntax. In languages such as Python, JSON feels like a first-class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code.

    • Trivial integration. Our whole code consists of a single header file json.hpp. That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.

    • Serious testing. Our class is heavily unit-tested and covers 100% of the code, including all exceptional behavior. Furthermore, we checked with Valgrind and the Clang Sanitizers that there are no memory leaks. Google OSS-Fuzz additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the Core Infrastructure Initiative (CII) best practices.

    Other aspects were not so important to us:

    • Memory efficiency. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: std::string for strings, int64_t, uint64_t or double for numbers, std::map for objects, std::vector for arrays, and bool for Booleans. However, you can template the generalized class basic_json to your needs.

    • Speed. There are certainly faster JSON libraries out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a std::vector or std::map, you are already set.

    See the contribution guidelines for more information.

    \ No newline at end of file + Design goals - JSON for Modern C++

    Design goals

    There are myriads of JSON libraries out there, and each may even have its reason to exist. Our class had these design goals:

    • Intuitive syntax. In languages such as Python, JSON feels like a first-class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code.

    • Trivial integration. Our whole code consists of a single header file json.hpp. That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.

    • Serious testing. Our class is heavily unit-tested and covers 100% of the code, including all exceptional behavior. Furthermore, we checked with Valgrind and the Clang Sanitizers that there are no memory leaks. Google OSS-Fuzz additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the Core Infrastructure Initiative (CII) best practices.

    Other aspects were not so important to us:

    • Memory efficiency. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: std::string for strings, int64_t, uint64_t or double for numbers, std::map for objects, std::vector for arrays, and bool for Booleans. However, you can template the generalized class basic_json to your needs.

    • Speed. There are certainly faster JSON libraries out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a std::vector or std::map, you are already set.

    See the contribution guidelines for more information.

    \ No newline at end of file diff --git a/home/design_goals/index.md b/home/design_goals/index.md new file mode 100644 index 000000000..41e057b28 --- /dev/null +++ b/home/design_goals/index.md @@ -0,0 +1,14 @@ +# Design goals + +There are myriads of [JSON](https://json.org) libraries out there, and each may even have its reason to exist. Our class had these design goals: + +- **Intuitive syntax**. In languages such as Python, JSON feels like a first-class data type. We used all the operator magic of modern C++ to achieve the same feeling in your code. +- **Trivial integration**. Our whole code consists of a single header file [`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp). That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings. +- **Serious testing**. Our class is heavily [unit-tested](https://github.com/nlohmann/json/tree/develop/tests/src) and covers [100%](https://coveralls.io/r/nlohmann/json) of the code, including all exceptional behavior. Furthermore, we checked with [Valgrind](http://valgrind.org) and the [Clang Sanitizers](https://clang.llvm.org/docs/index.html) that there are no memory leaks. [Google OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/json) additionally runs fuzz tests against all parsers 24/7, effectively executing billions of tests so far. To maintain high quality, the project is following the [Core Infrastructure Initiative (CII) best practices](https://bestpractices.coreinfrastructure.org/projects/289). + +Other aspects were not so important to us: + +- **Memory efficiency**. Each JSON object has an overhead of one pointer (the maximal size of a union) and one enumeration element (1 byte). The default generalization uses the following C++ data types: `std::string` for strings, `int64_t`, `uint64_t` or `double` for numbers, `std::map` for objects, `std::vector` for arrays, and `bool` for Booleans. However, you can template the generalized class `basic_json` to your needs. +- **Speed**. There are certainly [faster JSON libraries](https://github.com/miloyip/nativejson-benchmark#parsing-time) out there. However, if your goal is to speed up your development by adding JSON support with a single header, then this library is the way to go. If you know how to use a `std::vector` or `std::map`, you are already set. + +See the [contribution guidelines](https://github.com/nlohmann/json/blob/master/.github/CONTRIBUTING.md#please-dont) for more information. diff --git a/home/exceptions.md b/home/exceptions.md new file mode 100644 index 000000000..d6e626920 --- /dev/null +++ b/home/exceptions.md @@ -0,0 +1,929 @@ +# Exceptions + +## Overview + +### Base type + +All exceptions inherit from class `json::exception` (which in turn inherits from `std::exception`). It is used as the base class for all exceptions thrown by the `basic_json` class. This class can hence be used as "wildcard" to catch exceptions. + +``` mermaid +classDiagram + direction LR + class `std::exception` { + <> + } + + class `json::exception` { + +const int id + +const char* what() const + } + + class `json::parse_error` { + +const std::size_t byte + } + + class `json::invalid_iterator` + class `json::type_error` + class `json::out_of_range` + class `json::other_error` + + `std::exception` <|-- `json::exception` + `json::exception` <|-- `json::parse_error` + `json::exception` <|-- `json::invalid_iterator` + `json::exception` <|-- `json::type_error` + `json::exception` <|-- `json::out_of_range` + `json::exception` <|-- `json::other_error` +``` + +### Switch off exceptions + +Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol [`JSON_NOEXCEPTION`](../api/macros/json_noexception.md). In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `#!cpp throw`), `JSON_TRY_USER` (overriding `#!cpp try`), and `JSON_CATCH_USER` (overriding `#!cpp catch`). + +Note that [`JSON_THROW_USER`](../api/macros/json_throw_user.md) should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior. + +??? example + + The code below switches off exceptions and creates a log entry with a detailed error message in case of errors. + + ```cpp + #include + + #define JSON_TRY_USER if(true) + #define JSON_CATCH_USER(exception) if(false) + #define JSON_THROW_USER(exception) \ + {std::clog << "Error in " << __FILE__ << ":" << __LINE__ \ + << " (function " << __FUNCTION__ << ") - " \ + << (exception).what() << std::endl; \ + std::abort();} + + #include + ``` + +Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824). + +See [documentation of `JSON_TRY_USER`, `JSON_CATCH_USER` and `JSON_THROW_USER`](../api/macros/json_throw_user.md) for more information. + +### Extended diagnostic messages + +Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult. + +??? example + + ```cpp + --8<-- "examples/diagnostics_standard.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_standard.output" + ``` + + This exception can be hard to debug if storing the value `#!c "12"` and accessing it is further apart. + +To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that led to the exception) can be created. That global context is provided as [JSON Pointer](../features/json_pointer.md). + +As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) to `1` before including `json.hpp`. + +??? example + + ```cpp + --8<-- "examples/diagnostics_extended.cpp" + ``` + + Output: + + ``` + --8<-- "examples/diagnostics_extended.output" + ``` + + Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type. + +See [documentation of `JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) for more information. + +## Parse errors + +The library throws this exception when a parse error occurs. Parse errors +can occur during the deserialization of JSON text, CBOR, MessagePack, as well +as when using JSON Patch. + +Exceptions have ids 1xx. + +!!! info "Byte index" + + Member `byte` holds the byte index of the last read character in the input + file. + + For an input with n bytes, 1 is the index of the first character and n+1 + is the index of the terminating null byte or the end of file. This also + holds true when reading a byte vector (CBOR or MessagePack). + +??? example + + The following code shows how a `parse_error` exception can be caught. + + ```cpp + --8<-- "examples/parse_error.cpp" + ``` + + Output: + + ``` + --8<-- "examples/parse_error.output" + ``` + + +### json.exception.parse_error.101 + +This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member `byte` indicates the error position. + +!!! failure "Example message" + + Input ended prematurely: + + ``` + [json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal + ``` + + No input: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON + ``` + + Control character was not escaped: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \u0009 or \\; last read: '"'" + ``` + + String was not closed: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '"' + ``` + + Invalid number format: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E' + ``` + + `\u` was not be followed by four hex digits: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\u' must be followed by 4 hex digits; last read: '"\u01"' + ``` + + Invalid UTF-8 surrogate pair: + + ``` + [json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '"\uD7FF\uDC00'" + ``` + + Invalid UTF-8 byte: + + ``` + [json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"vous \352t' + ``` + +!!! tip + + - Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened. + - Paste the input to a JSON validator like or a tool like [jq](https://stedolan.github.io/jq/). + +### json.exception.parse_error.102 + +JSON uses the `\uxxxx` format to describe Unicode characters. Code points above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. + +!!! failure "Example message" + + ``` + parse error at 14: missing or wrong low surrogate + ``` + +!!! note + + This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used. + +### json.exception.parse_error.103 + +Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. + +!!! failure "Example message" + + ``` + parse error: code points above 0x10FFFF are invalid + ``` + +!!! note + + This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used. + +### json.exception.parse_error.104 + +[RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.104] parse error: JSON patch must be an array of objects + ``` + +### json.exception.parse_error.105 + +An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.105] parse error: operation 'add' must have member 'value' + ``` + ``` + [json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from' + ``` + ``` + [json.exception.parse_error.105] parse error: operation value 'foo' is invalid + ``` + +### json.exception.parse_error.106 + +An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.106] parse error: array index '01' must not begin with '0' + ``` + +### json.exception.parse_error.107 + +A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo' + ``` + +### json.exception.parse_error.108 + +In a JSON Pointer, only `~0` and `~1` are valid escape sequences. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' + ``` + +### json.exception.parse_error.109 + +A JSON Pointer array index must be a number. + +!!! failure "Example messages" + + ``` + [json.exception.parse_error.109] parse error: array index 'one' is not a number + ``` + ``` + [json.exception.parse_error.109] parse error: array index '+1' is not a number + ``` + +### json.exception.parse_error.110 + +When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input + ``` + ``` + [json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A + ``` + +### json.exception.parse_error.112 + +An unexpected byte was read in a [binary format](../features/binary_formats/index.md) or length information is invalid ([BSON](../features/binary_formats/bson.md)). + +!!! failure "Example messages" + + ``` + [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C + ``` + ``` + [json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648 + ``` + ``` + [json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1 + ``` + +### json.exception.parse_error.113 + +While parsing a map key, a value that is not a string has been read. + +!!! failure "Example messages" + + ``` + [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF + ``` + ``` + [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF + ``` + ``` + [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82 + ``` + +### json.exception.parse_error.114 + +The parsing of the corresponding BSON record type is not implemented (yet). + +!!! failure "Example message" + + ``` + [json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF + ``` + +### json.exception.parse_error.115 + +A UBJSON high-precision number could not be parsed. + +!!! failure "Example message" + + ``` + [json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A + ``` + +## Iterator errors + +This exception is thrown if iterators passed to a library function do not match +the expected semantics. + +Exceptions have ids 2xx. + +??? example + + The following code shows how an `invalid_iterator` exception can be caught. + + ```cpp + --8<-- "examples/invalid_iterator.cpp" + ``` + + Output: + + ``` + --8<-- "examples/invalid_iterator.output" + ``` + +### json.exception.invalid_iterator.201 + +The iterators passed to constructor `basic_json(InputIT first, InputIT last)` are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.201] iterators are not compatible + ``` + +### json.exception.invalid_iterator.202 + +In the [erase](../api/basic_json/erase.md) or insert function, the passed iterator `pos` does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. + +!!! failure "Example messages" + + ``` + [json.exception.invalid_iterator.202] iterator does not fit current value + ``` + ``` + [json.exception.invalid_iterator.202] iterators first and last must point to objects + ``` + +### json.exception.invalid_iterator.203 + +Either iterator passed to function [`erase(IteratorType first, IteratorType last`)](../api/basic_json/erase.md) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.203] iterators do not fit current value + ``` + +### json.exception.invalid_iterator.204 + +When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an [erase](../api/basic_json/erase.md) function, this range has to be exactly (`begin(),` `end()),` because this is the only way the single stored value is expressed. All other ranges are invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.204] iterators out of range + ``` + +### json.exception.invalid_iterator.205 + +When an iterator for a primitive type (number, boolean, or string) is passed to an [erase](../api/basic_json/erase.md) function, the iterator has to be the `begin()` iterator, because it is the only way to address the stored value. All other iterators are invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.205] iterator out of range + ``` + +### json.exception.invalid_iterator.206 + +The iterators passed to constructor `basic_json(InputIT first, InputIT last)` belong to a JSON null value and hence to not define a valid range. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.206] cannot construct with iterators from null + ``` + +### json.exception.invalid_iterator.207 + +The `key()` member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.207] cannot use key() for non-object iterators + ``` + + +### json.exception.invalid_iterator.208 + +The `operator[]` to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.208] cannot use operator[] for object iterators + ``` + +### json.exception.invalid_iterator.209 + +The offset operators (`+`, `-`, `+=`, `-=`) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.209] cannot use offsets with object iterators + ``` + +### json.exception.invalid_iterator.210 + +The iterator range passed to the insert function is not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.210] iterators do not fit + ``` + +### json.exception.invalid_iterator.211 + +The iterator range passed to the insert function must not be a subrange of the container to insert to. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.211] passed iterators may not belong to container + ``` + +### json.exception.invalid_iterator.212 + +When two iterators are compared, they must belong to the same container. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.212] cannot compare iterators of different containers + ``` + +### json.exception.invalid_iterator.213 + +The order of object iterators cannot be compared, because JSON objects are unordered. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.213] cannot compare order of object iterators + ``` + +### json.exception.invalid_iterator.214 + +Cannot retrieve value from iterator: The iterator either refers to a null value, or it refers to a primitive type (number, boolean, or string), but does not match the iterator returned by `begin()`. + +!!! failure "Example message" + + ``` + [json.exception.invalid_iterator.214] cannot get value + ``` + +## Type errors + +This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics. + +Exceptions have ids 3xx. + +??? example + + The following code shows how a `type_error` exception can be caught. + + ```cpp + --8<-- "examples/type_error.cpp" + ``` + + Output: + + ``` + --8<-- "examples/type_error.output" + ``` + +### json.exception.type_error.301 + +To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. + +!!! failure "Example message" + + ``` + [json.exception.type_error.301] cannot create object from initializer list + ``` + +### json.exception.type_error.302 + +During implicit or explicit value conversion, the JSON type must be compatible with the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.302] type must be object, but is null + ``` + ``` + [json.exception.type_error.302] type must be string, but is object + ``` + +### json.exception.type_error.303 + +To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object + ``` + ``` + [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number" + ``` + +### json.exception.type_error.304 + +The `at()` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.304] cannot use at() with string + ``` + ``` + [json.exception.type_error.304] cannot use at() with number + ``` + +### json.exception.type_error.305 + +The `operator[]` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.305] cannot use operator[] with a string argument with array + ``` + ``` + [json.exception.type_error.305] cannot use operator[] with a numeric argument with object + ``` + +### json.exception.type_error.306 + +The `value()` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.306] cannot use value() with number + ``` + +### json.exception.type_error.307 + +The [`erase()`](../api/basic_json/erase.md) member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.307] cannot use erase() with string + ``` + +### json.exception.type_error.308 + +The `push_back()` and `operator+=` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.308] cannot use push_back() with string + ``` + +### json.exception.type_error.309 + +The `insert()` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.309] cannot use insert() with array + ``` + ``` + [json.exception.type_error.309] cannot use insert() with number + ``` + +### json.exception.type_error.310 + +The `swap()` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.310] cannot use swap() with number + ``` + +### json.exception.type_error.311 + +The `emplace()` and `emplace_back()` member functions can only be executed for certain JSON types. + +!!! failure "Example messages" + + ``` + [json.exception.type_error.311] cannot use emplace() with number + ``` + ``` + [json.exception.type_error.311] cannot use emplace_back() with number + ``` + +### json.exception.type_error.312 + +The `update()` member functions can only be executed for certain JSON types. + +!!! failure "Example message" + + ``` + [json.exception.type_error.312] cannot use update() with array + ``` + +### json.exception.type_error.313 + +The `unflatten` function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well-defined. + +!!! failure "Example message" + + ``` + [json.exception.type_error.313] invalid value to unflatten + ``` + +### json.exception.type_error.314 + +The `unflatten` function only works for an object whose keys are JSON Pointers. + +!!! failure "Example message" + + Calling `unflatten()` on an array `#!json [1,2,3]`: + + ``` + [json.exception.type_error.314] only objects can be unflattened + ``` + +### json.exception.type_error.315 + +The `unflatten()` function only works for an object whose keys are JSON Pointers and whose values are primitive. + +!!! failure "Example message" + + Calling `unflatten()` on an object `#!json {"/1", [1,2,3]}`: + + ``` + [json.exception.type_error.315] values in object must be primitive + ``` + +### json.exception.type_error.316 + +The `dump()` function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. + +!!! failure "Example message" + + Calling `dump()` on a JSON value containing an ISO 8859-1 encoded string: + ``` + [json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F + ``` + +!!! tip + + - Store the source file with UTF-8 encoding. + - Pass an error handler as last parameter to the `dump()` function to avoid this exception: + - `json::error_handler_t::replace` will replace invalid bytes sequences with `U+FFFD` + - `json::error_handler_t::ignore` will silently ignore invalid byte sequences + +### json.exception.type_error.317 + +The dynamic type of the object cannot be represented in the requested serialization format (e.g., a raw `true` or `null` JSON object cannot be serialized to BSON) + +!!! failure "Example messages" + + Serializing `#!json null` to BSON: + ``` + [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null + ``` + Serializing `#!json [1,2,3]` to BSON: + ``` + [json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array + ``` + +!!! tip + + Encapsulate the JSON value in an object. That is, instead of serializing `#!json true`, serialize `#!json {"value": true}` + +## Out of range + +This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys. + +Exceptions have ids 4xx. + +??? example + + The following code shows how an `out_of_range` exception can be caught. + + ```cpp + --8<-- "examples/out_of_range.cpp" + ``` + + Output: + + ``` + --8<-- "examples/out_of_range.output" + ``` + +### json.exception.out_of_range.401 + +The provided array index `i` is larger than `size-1`. + +!!! failure "Example message" + + ``` + array index 3 is out of range + ``` + +### json.exception.out_of_range.402 + +The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. + +!!! failure "Example message" + + ``` + array index '-' (3) is out of range + ``` + +### json.exception.out_of_range.403 + +The provided key was not found in the JSON object. + +!!! failure "Example message" + + ``` + key 'foo' not found + ``` + +### json.exception.out_of_range.404 + +A reference token in a JSON Pointer could not be resolved. + +!!! failure "Example message" + + ``` + unresolved reference token 'foo' + ``` + +### json.exception.out_of_range.405 + +The JSON Patch operations 'remove' and 'add' cannot be applied to the root element of the JSON value. + +!!! failure "Example message" + + ``` + JSON pointer has no parent + ``` + +### json.exception.out_of_range.406 + +A parsed number could not be stored as without changing it to NaN or INF. + +!!! failure "Example message" + + ``` + number overflow parsing '10E1000' + ``` + +### json.exception.out_of_range.407 + +This exception previously indicated that the UBJSON and BSON binary formats did not support integer numbers greater than +9223372036854775807 due to limitations in the implemented mapping. However, these limitations have since been resolved, +and this exception no longer occurs. + +!!! success "Exception cannot occur any more" + + - Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers. + - Since version 3.12.0, integer numbers beyond int64 are serialized as uint64 BSON numbers. + +### json.exception.out_of_range.408 + +The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. + +!!! failure "Example message" + + ``` + excessive array size: 8658170730974374167 + ``` + +### json.exception.out_of_range.409 + +Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string. + +!!! failure "Example message" + + ``` + BSON key cannot contain code point U+0000 (at byte 2) + ``` + +### json.exception.out_of_range.410 + +This exception is thrown when an undefined value is used with +[`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](../api/macros/nlohmann_json_serialize_enum_strict.md), or when an array index in +a JSON pointer exceeds the range of `size_type` (e.g., on 32-bit platforms). + +!!! failure "Example message" + + ``` + enum value out of range + array index 18446744073709551616 exceeds size_type + ``` + +### json.exception.out_of_range.411 + +A JSON Patch `add` operation cannot be applied because the target location's parent is neither an object nor an array. Per [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902), an `add` target must reference a member of an existing object or an element of an existing array; a primitive value (string, number, boolean, etc.) cannot receive a new member or element. + +!!! failure "Example message" + + ``` + cannot add value: the JSON Patch 'add' target's parent is of type string, but must be an object or array + ``` + +!!! note + + This exception was added in version 3.12.x. Before that, this situation hit an internal assertion (aborting the program in debug builds) or was silently ignored when assertions were disabled. + +## Further exceptions + +This exception is thrown in case of errors that cannot be classified with the +other exception types. + +Exceptions have ids 5xx. + +??? example + + The following code shows how an `other_error` exception can be caught. + + ```cpp + --8<-- "examples/other_error.cpp" + ``` + + Output: + + ``` + --8<-- "examples/other_error.output" + ``` + +### json.exception.other_error.501 + +A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. + +!!! failure "Example message" + + Executing `#!json {"op":"test", "path":"/baz", "value":"bar"}` on `#!json {"baz": "qux"}`: + + ``` + [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/baz","value":"bar"} + ``` diff --git a/home/exceptions/index.html b/home/exceptions/index.html index 999b67f94..1e2558b19 100644 --- a/home/exceptions/index.html +++ b/home/exceptions/index.html @@ -283,4 +283,4 @@ array index 18446744073709551616 exceeds size_type

    Output:

    message: [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/best_biscuit/name","value":"Choco Leibniz"}
     exception id: 501
     

    json.exception.other_error.501

    A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.

    Example message

    Executing {"op":"test", "path":"/baz", "value":"bar"} on {"baz": "qux"}:

    [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/baz","value":"bar"}
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/home/exceptions/index.md b/home/exceptions/index.md new file mode 100644 index 000000000..4e5c44499 --- /dev/null +++ b/home/exceptions/index.md @@ -0,0 +1,1090 @@ +# Exceptions + +## Overview + +### Base type + +All exceptions inherit from class `json::exception` (which in turn inherits from `std::exception`). It is used as the base class for all exceptions thrown by the `basic_json` class. This class can hence be used as "wildcard" to catch exceptions. + +``` +classDiagram + direction LR + class `std::exception` { + <> + } + + class `json::exception` { + +const int id + +const char* what() const + } + + class `json::parse_error` { + +const std::size_t byte + } + + class `json::invalid_iterator` + class `json::type_error` + class `json::out_of_range` + class `json::other_error` + + `std::exception` <|-- `json::exception` + `json::exception` <|-- `json::parse_error` + `json::exception` <|-- `json::invalid_iterator` + `json::exception` <|-- `json::type_error` + `json::exception` <|-- `json::out_of_range` + `json::exception` <|-- `json::other_error` +``` + +### Switch off exceptions + +Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol [`JSON_NOEXCEPTION`](https://json.nlohmann.me/api/macros/json_noexception/index.md). In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). + +Note that [`JSON_THROW_USER`](https://json.nlohmann.me/api/macros/json_throw_user/index.md) should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior. + +Example + +The code below switches off exceptions and creates a log entry with a detailed error message in case of errors. + +``` +#include + +#define JSON_TRY_USER if(true) +#define JSON_CATCH_USER(exception) if(false) +#define JSON_THROW_USER(exception) \ + {std::clog << "Error in " << __FILE__ << ":" << __LINE__ \ + << " (function " << __FUNCTION__ << ") - " \ + << (exception).what() << std::endl; \ + std::abort();} + +#include +``` + +Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824). + +See [documentation of `JSON_TRY_USER`, `JSON_CATCH_USER` and `JSON_THROW_USER`](https://json.nlohmann.me/api/macros/json_throw_user/index.md) for more information. + +### Extended diagnostic messages + +Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult. + +Example + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + json j; + j["address"]["street"] = "Fake Street"; + j["address"]["housenumber"] = "12"; + + try + { + int housenumber = j["address"]["housenumber"]; + } + catch (const json::exception& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.type_error.302] type must be number, but is string +``` + +This exception can be hard to debug if storing the value `"12"` and accessing it is further apart. + +To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that led to the exception) can be created. That global context is provided as [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md). + +As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) to `1` before including `json.hpp`. + +Example + +``` +#include + +# define JSON_DIAGNOSTICS 1 +#include + +using json = nlohmann::json; + +int main() +{ + json j; + j["address"]["street"] = "Fake Street"; + j["address"]["housenumber"] = "12"; + + try + { + int housenumber = j["address"]["housenumber"]; + } + catch (const json::exception& e) + { + std::cout << e.what() << '\n'; + } +} +``` + +Output: + +``` +[json.exception.type_error.302] (/address/housenumber) type must be number, but is string +``` + +Now the exception message contains a JSON Pointer `/address/housenumber` that indicates which value has the wrong type. + +See [documentation of `JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) for more information. + +## Parse errors + +The library throws this exception when a parse error occurs. Parse errors can occur during the deserialization of JSON text, CBOR, MessagePack, as well as when using JSON Patch. + +Exceptions have ids 1xx. + +Byte index + +Member `byte` holds the byte index of the last read character in the input file. + +For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector (CBOR or MessagePack). + +Example + +The following code shows how a `parse_error` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // parsing input with a syntax error + json::parse("[1,2,3,]"); + } + catch (const json::parse_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << '\n' + << "byte position of error: " << e.byte << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal +exception id: 101 +byte position of error: 8 +``` + +### json.exception.parse_error.101 + +This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member `byte` indicates the error position. + +Example message + +Input ended prematurely: + +``` +[json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal +``` + +No input: + +``` +[json.exception.parse_error.101] parse error at line 1, column 1: attempting to parse an empty input; check that your input string or stream contains the expected JSON +``` + +Control character was not escaped: + +``` +[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to \u0009 or \\; last read: '"'" +``` + +String was not closed: + +``` +[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '"' +``` + +Invalid number format: + +``` +[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E' +``` + +`\u` was not be followed by four hex digits: + +``` +[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: '\u' must be followed by 4 hex digits; last read: '"\u01"' +``` + +Invalid UTF-8 surrogate pair: + +``` +[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '"\uD7FF\uDC00'" +``` + +Invalid UTF-8 byte: + +``` +[json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"vous \352t' +``` + +Tip + +- Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened. +- Paste the input to a JSON validator like or a tool like [jq](https://stedolan.github.io/jq/). + +### json.exception.parse_error.102 + +JSON uses the `\uxxxx` format to describe Unicode characters. Code points above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point. + +Example message + +``` +parse error at 14: missing or wrong low surrogate +``` + +Note + +This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used. + +### json.exception.parse_error.103 + +Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. + +Example message + +``` +parse error: code points above 0x10FFFF are invalid +``` + +Note + +This exception is not used any more. Instead [json.exception.parse_error.101](#jsonexceptionparse_error101) with a more detailed description is used. + +### json.exception.parse_error.104 + +[RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. + +Example message + +``` +[json.exception.parse_error.104] parse error: JSON patch must be an array of objects +``` + +### json.exception.parse_error.105 + +An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors. + +Example message + +``` +[json.exception.parse_error.105] parse error: operation 'add' must have member 'value' +``` + +``` +[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from' +``` + +``` +[json.exception.parse_error.105] parse error: operation value 'foo' is invalid +``` + +### json.exception.parse_error.106 + +An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. + +Example message + +``` +[json.exception.parse_error.106] parse error: array index '01' must not begin with '0' +``` + +### json.exception.parse_error.107 + +A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. + +Example message + +``` +[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo' +``` + +### json.exception.parse_error.108 + +In a JSON Pointer, only `~0` and `~1` are valid escape sequences. + +Example message + +``` +[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1' +``` + +### json.exception.parse_error.109 + +A JSON Pointer array index must be a number. + +Example messages + +``` +[json.exception.parse_error.109] parse error: array index 'one' is not a number +``` + +``` +[json.exception.parse_error.109] parse error: array index '+1' is not a number +``` + +### json.exception.parse_error.110 + +When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. + +Example message + +``` +[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input +``` + +``` +[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A +``` + +### json.exception.parse_error.112 + +An unexpected byte was read in a [binary format](https://json.nlohmann.me/features/binary_formats/index.md) or length information is invalid ([BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md)). + +Example messages + +``` +[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C +``` + +``` +[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1 +``` + +``` +[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02 +``` + +``` +[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02 +``` + +``` +[json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648 +``` + +``` +[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1 +``` + +### json.exception.parse_error.113 + +While parsing a map key, a value that is not a string has been read. + +Example messages + +``` +[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF +``` + +``` +[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF +``` + +``` +[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82 +``` + +### json.exception.parse_error.114 + +The parsing of the corresponding BSON record type is not implemented (yet). + +Example message + +``` +[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF +``` + +### json.exception.parse_error.115 + +A UBJSON high-precision number could not be parsed. + +Example message + +``` +[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A +``` + +## Iterator errors + +This exception is thrown if iterators passed to a library function do not match the expected semantics. + +Exceptions have ids 2xx. + +Example + +The following code shows how an `invalid_iterator` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling iterator::key() on non-object iterator + json j = "string"; + json::iterator it = j.begin(); + auto k = it.key(); + } + catch (const json::invalid_iterator& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators +exception id: 207 +``` + +### json.exception.invalid_iterator.201 + +The iterators passed to constructor `basic_json(InputIT first, InputIT last)` are not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid. + +Example message + +``` +[json.exception.invalid_iterator.201] iterators are not compatible +``` + +### json.exception.invalid_iterator.202 + +In the [erase](https://json.nlohmann.me/api/basic_json/erase/index.md) or insert function, the passed iterator `pos` does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion. + +Example messages + +``` +[json.exception.invalid_iterator.202] iterator does not fit current value +``` + +``` +[json.exception.invalid_iterator.202] iterators first and last must point to objects +``` + +### json.exception.invalid_iterator.203 + +Either iterator passed to function [`erase(IteratorType first, IteratorType last`)](https://json.nlohmann.me/api/basic_json/erase/index.md) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from. + +Example message + +``` +[json.exception.invalid_iterator.203] iterators do not fit current value +``` + +### json.exception.invalid_iterator.204 + +When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an [erase](https://json.nlohmann.me/api/basic_json/erase/index.md) function, this range has to be exactly (`begin(),` `end()),` because this is the only way the single stored value is expressed. All other ranges are invalid. + +Example message + +``` +[json.exception.invalid_iterator.204] iterators out of range +``` + +### json.exception.invalid_iterator.205 + +When an iterator for a primitive type (number, boolean, or string) is passed to an [erase](https://json.nlohmann.me/api/basic_json/erase/index.md) function, the iterator has to be the `begin()` iterator, because it is the only way to address the stored value. All other iterators are invalid. + +Example message + +``` +[json.exception.invalid_iterator.205] iterator out of range +``` + +### json.exception.invalid_iterator.206 + +The iterators passed to constructor `basic_json(InputIT first, InputIT last)` belong to a JSON null value and hence to not define a valid range. + +Example message + +``` +[json.exception.invalid_iterator.206] cannot construct with iterators from null +``` + +### json.exception.invalid_iterator.207 + +The `key()` member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key. + +Example message + +``` +[json.exception.invalid_iterator.207] cannot use key() for non-object iterators +``` + +### json.exception.invalid_iterator.208 + +The `operator[]` to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. + +Example message + +``` +[json.exception.invalid_iterator.208] cannot use operator[] for object iterators +``` + +### json.exception.invalid_iterator.209 + +The offset operators (`+`, `-`, `+=`, `-=`) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. + +Example message + +``` +[json.exception.invalid_iterator.209] cannot use offsets with object iterators +``` + +### json.exception.invalid_iterator.210 + +The iterator range passed to the insert function is not compatible, meaning they do not belong to the same container. Therefore, the range (`first`, `last`) is invalid. + +Example message + +``` +[json.exception.invalid_iterator.210] iterators do not fit +``` + +### json.exception.invalid_iterator.211 + +The iterator range passed to the insert function must not be a subrange of the container to insert to. + +Example message + +``` +[json.exception.invalid_iterator.211] passed iterators may not belong to container +``` + +### json.exception.invalid_iterator.212 + +When two iterators are compared, they must belong to the same container. + +Example message + +``` +[json.exception.invalid_iterator.212] cannot compare iterators of different containers +``` + +### json.exception.invalid_iterator.213 + +The order of object iterators cannot be compared, because JSON objects are unordered. + +Example message + +``` +[json.exception.invalid_iterator.213] cannot compare order of object iterators +``` + +### json.exception.invalid_iterator.214 + +Cannot retrieve value from iterator: The iterator either refers to a null value, or it refers to a primitive type (number, boolean, or string), but does not match the iterator returned by `begin()`. + +Example message + +``` +[json.exception.invalid_iterator.214] cannot get value +``` + +## Type errors + +This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics. + +Exceptions have ids 3xx. + +Example + +The following code shows how a `type_error` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling push_back() on a string value + json j = "string"; + j.push_back("another string"); + } + catch (const json::type_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.type_error.308] cannot use push_back() with string +exception id: 308 +``` + +### json.exception.type_error.301 + +To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. + +Example message + +``` +[json.exception.type_error.301] cannot create object from initializer list +``` + +### json.exception.type_error.302 + +During implicit or explicit value conversion, the JSON type must be compatible with the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. + +Example messages + +``` +[json.exception.type_error.302] type must be object, but is null +``` + +``` +[json.exception.type_error.302] type must be string, but is object +``` + +### json.exception.type_error.303 + +To retrieve a reference to a value stored in a `basic_json` object with `get_ref`, the type of the reference must match the value type. For instance, for a JSON array, the `ReferenceType` must be `array_t &`. + +Example messages + +``` +[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object +``` + +``` +[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number" +``` + +### json.exception.type_error.304 + +The `at()` member functions can only be executed for certain JSON types. + +Example messages + +``` +[json.exception.type_error.304] cannot use at() with string +``` + +``` +[json.exception.type_error.304] cannot use at() with number +``` + +### json.exception.type_error.305 + +The `operator[]` member functions can only be executed for certain JSON types. + +Example messages + +``` +[json.exception.type_error.305] cannot use operator[] with a string argument with array +``` + +``` +[json.exception.type_error.305] cannot use operator[] with a numeric argument with object +``` + +### json.exception.type_error.306 + +The `value()` member functions can only be executed for certain JSON types. + +Example message + +``` +[json.exception.type_error.306] cannot use value() with number +``` + +### json.exception.type_error.307 + +The [`erase()`](https://json.nlohmann.me/api/basic_json/erase/index.md) member functions can only be executed for certain JSON types. + +Example message + +``` +[json.exception.type_error.307] cannot use erase() with string +``` + +### json.exception.type_error.308 + +The `push_back()` and `operator+=` member functions can only be executed for certain JSON types. + +Example message + +``` +[json.exception.type_error.308] cannot use push_back() with string +``` + +### json.exception.type_error.309 + +The `insert()` member functions can only be executed for certain JSON types. + +Example messages + +``` +[json.exception.type_error.309] cannot use insert() with array +``` + +``` +[json.exception.type_error.309] cannot use insert() with number +``` + +### json.exception.type_error.310 + +The `swap()` member functions can only be executed for certain JSON types. + +Example message + +``` +[json.exception.type_error.310] cannot use swap() with number +``` + +### json.exception.type_error.311 + +The `emplace()` and `emplace_back()` member functions can only be executed for certain JSON types. + +Example messages + +``` +[json.exception.type_error.311] cannot use emplace() with number +``` + +``` +[json.exception.type_error.311] cannot use emplace_back() with number +``` + +### json.exception.type_error.312 + +The `update()` member functions can only be executed for certain JSON types. + +Example message + +``` +[json.exception.type_error.312] cannot use update() with array +``` + +### json.exception.type_error.313 + +The `unflatten` function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well-defined. + +Example message + +``` +[json.exception.type_error.313] invalid value to unflatten +``` + +### json.exception.type_error.314 + +The `unflatten` function only works for an object whose keys are JSON Pointers. + +Example message + +Calling `unflatten()` on an array `[1,2,3]`: + +``` +[json.exception.type_error.314] only objects can be unflattened +``` + +### json.exception.type_error.315 + +The `unflatten()` function only works for an object whose keys are JSON Pointers and whose values are primitive. + +Example message + +Calling `unflatten()` on an object `{"/1", [1,2,3]}`: + +``` +[json.exception.type_error.315] values in object must be primitive +``` + +### json.exception.type_error.316 + +The `dump()` function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. + +Example message + +Calling `dump()` on a JSON value containing an ISO 8859-1 encoded string: + +``` +[json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F +``` + +Tip + +- Store the source file with UTF-8 encoding. +- Pass an error handler as last parameter to the `dump()` function to avoid this exception: + - `json::error_handler_t::replace` will replace invalid bytes sequences with `U+FFFD` + - `json::error_handler_t::ignore` will silently ignore invalid byte sequences + +### json.exception.type_error.317 + +The dynamic type of the object cannot be represented in the requested serialization format (e.g., a raw `true` or `null` JSON object cannot be serialized to BSON) + +Example messages + +Serializing `null` to BSON: + +``` +[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null +``` + +Serializing `[1,2,3]` to BSON: + +``` +[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array +``` + +Tip + +Encapsulate the JSON value in an object. That is, instead of serializing `true`, serialize `{"value": true}` + +## Out of range + +This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance, in the case of array indices or nonexisting object keys. + +Exceptions have ids 4xx. + +Example + +The following code shows how an `out_of_range` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // calling at() for an invalid index + json j = {1, 2, 3, 4}; + j.at(4) = 10; + } + catch (const json::out_of_range& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.out_of_range.401] array index 4 is out of range +exception id: 401 +``` + +### json.exception.out_of_range.401 + +The provided array index `i` is larger than `size-1`. + +Example message + +``` +array index 3 is out of range +``` + +### json.exception.out_of_range.402 + +The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it. + +Example message + +``` +array index '-' (3) is out of range +``` + +### json.exception.out_of_range.403 + +The provided key was not found in the JSON object. + +Example message + +``` +key 'foo' not found +``` + +### json.exception.out_of_range.404 + +A reference token in a JSON Pointer could not be resolved. + +Example message + +``` +unresolved reference token 'foo' +``` + +### json.exception.out_of_range.405 + +The JSON Patch operations 'remove' and 'add' cannot be applied to the root element of the JSON value. + +Example message + +``` +JSON pointer has no parent +``` + +### json.exception.out_of_range.406 + +A parsed number could not be stored as without changing it to NaN or INF. + +Example message + +``` +number overflow parsing '10E1000' +``` + +### json.exception.out_of_range.407 + +This exception previously indicated that the UBJSON and BSON binary formats did not support integer numbers greater than 9223372036854775807 due to limitations in the implemented mapping. However, these limitations have since been resolved, and this exception no longer occurs. + +Exception cannot occur any more + +- Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers. +- Since version 3.12.0, integer numbers beyond int64 are serialized as uint64 BSON numbers. + +### json.exception.out_of_range.408 + +The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. + +Example message + +``` +excessive array size: 8658170730974374167 +``` + +### json.exception.out_of_range.409 + +Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string. + +Example message + +``` +BSON key cannot contain code point U+0000 (at byte 2) +``` + +### json.exception.out_of_range.410 + +This exception is thrown when an undefined value is used with [`NLOHMANN_JSON_SERIALIZE_ENUM_STRICT`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/index.md), or when an array index in a JSON pointer exceeds the range of `size_type` (e.g., on 32-bit platforms). + +Example message + +``` +enum value out of range +array index 18446744073709551616 exceeds size_type +``` + +### json.exception.out_of_range.411 + +A JSON Patch `add` operation cannot be applied because the target location's parent is neither an object nor an array. Per [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902), an `add` target must reference a member of an existing object or an element of an existing array; a primitive value (string, number, boolean, etc.) cannot receive a new member or element. + +Example message + +``` +cannot add value: the JSON Patch 'add' target's parent is of type string, but must be an object or array +``` + +Note + +This exception was added in version 3.12.x. Before that, this situation hit an internal assertion (aborting the program in debug builds) or was silently ignored when assertions were disabled. + +## Further exceptions + +This exception is thrown in case of errors that cannot be classified with the other exception types. + +Exceptions have ids 5xx. + +Example + +The following code shows how an `other_error` exception can be caught. + +``` +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +int main() +{ + try + { + // executing a failing JSON Patch operation + json value = R"({ + "best_biscuit": { + "name": "Oreo" + } + })"_json; + json patch = R"([{ + "op": "test", + "path": "/best_biscuit/name", + "value": "Choco Leibniz" + }])"_json; + value.patch(patch); + } + catch (const json::other_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} +``` + +Output: + +``` +message: [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/best_biscuit/name","value":"Choco Leibniz"} +exception id: 501 +``` + +### json.exception.other_error.501 + +A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. + +Example message + +Executing `{"op":"test", "path":"/baz", "value":"bar"}` on `{"baz": "qux"}`: + +``` +[json.exception.other_error.501] unsuccessful: {"op":"test","path":"/baz","value":"bar"} +``` diff --git a/home/faq.md b/home/faq.md new file mode 100644 index 000000000..4af6fc0fa --- /dev/null +++ b/home/faq.md @@ -0,0 +1,225 @@ +# Frequently Asked Questions (FAQ) + +## Known bugs + +### Brace initialization yields arrays + +!!! question + + Why does + + ```cpp + json j{true}; + ``` + + and + + ```cpp + json j(true); + ``` + + yield different results (`#!json [true]` vs. `#!json true`)? + +This is a known issue, and -- even worse -- the behavior differs between GCC and Clang. The "culprit" for this is the library's constructor overloads for initializer lists to allow syntax like + +```cpp +json array = {1, 2, 3, 4}; +``` + +for arrays and + +```cpp +json object = {{"one", 1}, {"two", 2}}; +``` + +for objects. + +!!! tip + + To avoid any confusion and ensure portable code, **do not** use brace initialization with the types `basic_json`, `json`, or `ordered_json` unless you want to create an object or array as shown in the examples above. + + To explicitly create a single-element array, use `json::array({value})`: + + ```cpp + json j = json::array({true}); // [true] + ``` + +**Opt-in copy semantics (since version 3.12.0)** + +If you define `JSON_BRACE_INIT_COPY_SEMANTICS` to `1` before including the library, single-element brace initialization is treated as copy/move instead of creating a single-element array: + +```cpp +#define JSON_BRACE_INIT_COPY_SEMANTICS 1 +#include + +json obj = {{"key", "value"}}; +json j{obj}; // -> {"key":"value"} (copy, not array) +``` + +Without the macro (default behavior), `json j{obj}` creates `[{"key":"value"}]`. This opt-in macro fixes issue #5074 while preserving backwards compatibility for existing code. + +## Limitations + +### Relaxed parsing + +!!! question + + Can you add an option to ignore trailing commas? + +This library does not support any feature that would jeopardize interoperability. + + +### Parse errors reading non-ASCII characters + +!!! question "Questions" + + - Why is the parser complaining about a Chinese character? + - Does the library support Unicode? + - I get an exception `[json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"Testé$')"` + +The library supports **Unicode input** as follows: + +- Only **UTF-8** encoded input is supported, which is the default encoding for JSON, according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1). +- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers. +- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors. +- The library will not replace [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1). +- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors. +- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs. +- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers. + +In most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows, where Latin-1 or ISO 8859-1 is often the standard encoding. + + +### Wide string handling + +!!! question + + Why are wide strings (e.g., `std::wstring`) dumped as arrays of numbers? + +As described [above](#parse-errors-reading-non-ascii-characters), the library assumes UTF-8 as encoding. To store a wide string, you need to change the encoding. + +!!! example + + ```cpp + #include // codecvt_utf8 + #include // wstring_convert + + // encoding function + std::string to_utf8(std::wstring& wide_string) + { + static std::wstring_convert> utf8_conv; + return utf8_conv.to_bytes(wide_string); + } + + json j; + std::wstring ws = L"車B1234 こんにちは"; + + j["original"] = ws; + j["encoded"] = to_utf8(ws); + + std::cout << j << std::endl; + ``` + + The result is: + + ```json + { + "encoded": "車B1234 こんにちは", + "original": [36554, 66, 49, 50, 51, 52, 32, 12371, 12435, 12395, 12385, 12399] + } + ``` + +## Exceptions + +### Parsing without exceptions + +!!! question + + Is it possible to indicate a parse error without throwing an exception? + +Yes, see [Parsing and exceptions](../features/parsing/parse_exceptions.md). + + +### Key name in exceptions + +!!! question + + Can I get the key of the object item that caused an exception? + +Yes, you can. Please define the symbol [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md) to get [extended diagnostics messages](exceptions.md#extended-diagnostic-messages). + + +## Serialization issues + + +### Number precision + +!!! question + + - It seems that precision is lost when serializing a double. + - Can I change the precision for floating-point serialization? + +The library uses `std::numeric_limits::digits10` (15 for IEEE `double`s) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip. + +!!! quote "[cppreference.com](https://en.cppreference.com/w/cpp/types/numeric_limits/digits10)" + + The value of `std::numeric_limits::digits10` is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow. + +!!! tip + + The website https://float.exposed gives a good insight into the internal storage of floating-point numbers. + +See [this section](../features/types/number_handling.md#number-serialization) on the library's number handling for more information. + +### Using JSON values with `std::format` or `fmt` + +!!! question + + - Can I use `std::format("{}", j)` on a JSON value? + - Can I use `fmt::format("{}", j)` or `fmt::print("{}", j)` (the [{fmt}](https://github.com/fmtlib/fmt) library) on a JSON value? + +`std::format` works out of the box since version 3.12.x, as long as the standard library provides +`` (see [`JSON_HAS_STD_FORMAT`](../api/macros/json_has_std_format.md)); see +[`std::formatter`](../api/basic_json/std_formatter.md) for details, including the `#!cpp "{:#}"` +pretty-print spec, indent widths (`#!cpp "{:2}"`), and custom indent characters (`#!cpp "{:.>#}"`). + +For `fmt`, the library ships [`format_as`](../api/basic_json/format_as.md), a small customization point +`fmt` looks for via argument-dependent lookup. It only has an effect on fmt 10.0.0 through 11.0.2 — from +fmt 11.1.0 onwards, `fmt` no longer picks up a `format_as` overload that returns a `std::string`. On such +versions (or any version, if you also want the same `#!cpp "{:#}"`/width/fill-and-align spec support that +`std::formatter` has), define your own `fmt::formatter` specialization; see +[`format_as`](../api/basic_json/format_as.md) for a recipe that mirrors it. + +If you get ambiguous-overload errors when passing a JSON value to `fmt::format`/`fmt::print` without any +`fmt::formatter` specialization in scope, that's `fmt` picking up `basic_json`'s implicit +`operator ValueType()` conversion operator (see [#964](https://github.com/nlohmann/json/issues/964) and +[#958](https://github.com/nlohmann/json/issues/958)); disabling it via +[`JSON_USE_IMPLICIT_CONVERSIONS 0`](../api/macros/json_use_implicit_conversions.md) avoids the ambiguity. + +## Compilation issues + +### Android SDK + +!!! question + + Why does the code not compile with Android SDK? + +Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. + +```ini +APP_STL := c++_shared +NDK_TOOLCHAIN_VERSION := clang3.6 +APP_CPPFLAGS += -frtti -fexceptions +``` + +The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10. + + +### Missing STL function + +!!! question "Questions" + + - Why do I get a compilation error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`)? + - Why does the code not compile with MinGW or Android SDK? + +This is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219). diff --git a/home/faq/index.html b/home/faq/index.html index 30861cd80..64ac6ddb3 100644 --- a/home/faq/index.html +++ b/home/faq/index.html @@ -32,4 +32,4 @@

    Exceptions

    Parsing without exceptions

    Question

    Is it possible to indicate a parse error without throwing an exception?

    Yes, see Parsing and exceptions.

    Key name in exceptions

    Question

    Can I get the key of the object item that caused an exception?

    Yes, you can. Please define the symbol JSON_DIAGNOSTICS to get extended diagnostics messages.

    Serialization issues

    Number precision

    Question

    • It seems that precision is lost when serializing a double.
    • Can I change the precision for floating-point serialization?

    The library uses std::numeric_limits<number_float_t>::digits10 (15 for IEEE doubles) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip.

    cppreference.com

    The value of std::numeric_limits<T>::digits10 is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow.

    Tip

    The website https://float.exposed gives a good insight into the internal storage of floating-point numbers.

    See this section on the library's number handling for more information.

    Using JSON values with std::format or fmt

    Question

    • Can I use std::format("{}", j) on a JSON value?
    • Can I use fmt::format("{}", j) or fmt::print("{}", j) (the {fmt} library) on a JSON value?

    std::format works out of the box since version 3.12.x, as long as the standard library provides <format> (see JSON_HAS_STD_FORMAT); see std::formatter<basic_json> for details, including the "{:#}" pretty-print spec, indent widths ("{:2}"), and custom indent characters ("{:.>#}").

    For fmt, the library ships format_as, a small customization point fmt looks for via argument-dependent lookup. It only has an effect on fmt 10.0.0 through 11.0.2 — from fmt 11.1.0 onwards, fmt no longer picks up a format_as overload that returns a std::string. On such versions (or any version, if you also want the same "{:#}"/width/fill-and-align spec support that std::formatter<basic_json> has), define your own fmt::formatter specialization; see format_as for a recipe that mirrors it.

    If you get ambiguous-overload errors when passing a JSON value to fmt::format/fmt::print without any fmt::formatter<json> specialization in scope, that's fmt picking up basic_json's implicit operator ValueType() conversion operator (see #964 and #958); disabling it via JSON_USE_IMPLICIT_CONVERSIONS 0 avoids the ambiguity.

    Compilation issues

    Android SDK

    Question

    Why does the code not compile with Android SDK?

    Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your Application.mk. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default.

    APP_STL := c++_shared
     NDK_TOOLCHAIN_VERSION := clang3.6
     APP_CPPFLAGS += -frtti -fexceptions
    -

    The code compiles successfully with Android NDK, Revision 9 - 11 (and possibly later) and CrystaX's Android NDK version 10.

    Missing STL function

    Questions

    • Why do I get a compilation error 'to_string' is not a member of 'std' (or similarly, for strtod or strtof)?
    • Why does the code not compile with MinGW or Android SDK?

    This is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to this site and this discussion for information on how to fix this bug. For Android NDK using APP_STL := gnustl_static, please refer to this discussion.

    \ No newline at end of file +

    The code compiles successfully with Android NDK, Revision 9 - 11 (and possibly later) and CrystaX's Android NDK version 10.

    Missing STL function

    Questions

    • Why do I get a compilation error 'to_string' is not a member of 'std' (or similarly, for strtod or strtof)?
    • Why does the code not compile with MinGW or Android SDK?

    This is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to this site and this discussion for information on how to fix this bug. For Android NDK using APP_STL := gnustl_static, please refer to this discussion.

    \ No newline at end of file diff --git a/home/faq/index.md b/home/faq/index.md new file mode 100644 index 000000000..ebc31e636 --- /dev/null +++ b/home/faq/index.md @@ -0,0 +1,207 @@ +# Frequently Asked Questions (FAQ) + +## Known bugs + +### Brace initialization yields arrays + +Question + +Why does + +``` +json j{true}; +``` + +and + +``` +json j(true); +``` + +yield different results (`[true]` vs. `true`)? + +This is a known issue, and -- even worse -- the behavior differs between GCC and Clang. The "culprit" for this is the library's constructor overloads for initializer lists to allow syntax like + +``` +json array = {1, 2, 3, 4}; +``` + +for arrays and + +``` +json object = {{"one", 1}, {"two", 2}}; +``` + +for objects. + +Tip + +To avoid any confusion and ensure portable code, **do not** use brace initialization with the types `basic_json`, `json`, or `ordered_json` unless you want to create an object or array as shown in the examples above. + +To explicitly create a single-element array, use `json::array({value})`: + +``` +json j = json::array({true}); // [true] +``` + +**Opt-in copy semantics (since version 3.12.0)** + +If you define `JSON_BRACE_INIT_COPY_SEMANTICS` to `1` before including the library, single-element brace initialization is treated as copy/move instead of creating a single-element array: + +``` +#define JSON_BRACE_INIT_COPY_SEMANTICS 1 +#include + +json obj = {{"key", "value"}}; +json j{obj}; // -> {"key":"value"} (copy, not array) +``` + +Without the macro (default behavior), `json j{obj}` creates `[{"key":"value"}]`. This opt-in macro fixes issue #5074 while preserving backwards compatibility for existing code. + +## Limitations + +### Relaxed parsing + +Question + +Can you add an option to ignore trailing commas? + +This library does not support any feature that would jeopardize interoperability. + +### Parse errors reading non-ASCII characters + +Questions + +- Why is the parser complaining about a Chinese character? +- Does the library support Unicode? +- I get an exception `[json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"Testé$')"` + +The library supports **Unicode input** as follows: + +- Only **UTF-8** encoded input is supported, which is the default encoding for JSON, according to [RFC 8259](https://tools.ietf.org/html/rfc8259.html#section-8.1). +- `std::u16string` and `std::u32string` can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers. +- Other encodings such as Latin-1 or ISO 8859-1 are **not** supported and will yield parse or serialization errors. +- The library will not replace [Unicode noncharacters](http://www.unicode.org/faq/private_use.html#nonchar1). +- Invalid surrogates (e.g., incomplete pairs such as `\uDEAD`) will yield parse errors. +- The strings stored in the library are UTF-8 encoded. When using the default string type (`std::string`), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs. +- When you store strings with different encodings in the library, calling [`dump()`](https://nlohmann.github.io/json/classnlohmann_1_1basic__json_a50ec80b02d0f3f51130d4abb5d1cfdc5.html#a50ec80b02d0f3f51130d4abb5d1cfdc5) may throw an exception unless `json::error_handler_t::replace` or `json::error_handler_t::ignore` are used as error handlers. + +In most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows, where Latin-1 or ISO 8859-1 is often the standard encoding. + +### Wide string handling + +Question + +Why are wide strings (e.g., `std::wstring`) dumped as arrays of numbers? + +As described [above](#parse-errors-reading-non-ascii-characters), the library assumes UTF-8 as encoding. To store a wide string, you need to change the encoding. + +Example + +``` +#include // codecvt_utf8 +#include // wstring_convert + +// encoding function +std::string to_utf8(std::wstring& wide_string) +{ + static std::wstring_convert> utf8_conv; + return utf8_conv.to_bytes(wide_string); +} + +json j; +std::wstring ws = L"車B1234 こんにちは"; + +j["original"] = ws; +j["encoded"] = to_utf8(ws); + +std::cout << j << std::endl; +``` + +The result is: + +``` +{ + "encoded": "車B1234 こんにちは", + "original": [36554, 66, 49, 50, 51, 52, 32, 12371, 12435, 12395, 12385, 12399] +} +``` + +## Exceptions + +### Parsing without exceptions + +Question + +Is it possible to indicate a parse error without throwing an exception? + +Yes, see [Parsing and exceptions](https://json.nlohmann.me/features/parsing/parse_exceptions/index.md). + +### Key name in exceptions + +Question + +Can I get the key of the object item that caused an exception? + +Yes, you can. Please define the symbol [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) to get [extended diagnostics messages](https://json.nlohmann.me/home/exceptions/#extended-diagnostic-messages). + +## Serialization issues + +### Number precision + +Question + +- It seems that precision is lost when serializing a double. +- Can I change the precision for floating-point serialization? + +The library uses `std::numeric_limits::digits10` (15 for IEEE `double`s) digits for serialization. This value is sufficient to guarantee roundtripping. If one uses more than this number of digits of precision, then string -> value -> string is not guaranteed to round-trip. + +[cppreference.com](https://en.cppreference.com/w/cpp/types/numeric_limits/digits10) + +The value of `std::numeric_limits::digits10` is the number of base-10 digits that can be represented by the type T without change, that is, any number with this many significant decimal digits can be converted to a value of type T and back to decimal form, without change due to rounding or overflow. + +Tip + +The website gives a good insight into the internal storage of floating-point numbers. + +See [this section](https://json.nlohmann.me/features/types/number_handling/#number-serialization) on the library's number handling for more information. + +### Using JSON values with `std::format` or `fmt` + +Question + +- Can I use `std::format("{}", j)` on a JSON value? +- Can I use `fmt::format("{}", j)` or `fmt::print("{}", j)` (the [{fmt}](https://github.com/fmtlib/fmt) library) on a JSON value? + +`std::format` works out of the box since version 3.12.x, as long as the standard library provides `` (see [`JSON_HAS_STD_FORMAT`](https://json.nlohmann.me/api/macros/json_has_std_format/index.md)); see [`std::formatter`](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) for details, including the `"{:#}"` pretty-print spec, indent widths (`"{:2}"`), and custom indent characters (`"{:.>#}"`). + +For `fmt`, the library ships [`format_as`](https://json.nlohmann.me/api/basic_json/format_as/index.md), a small customization point `fmt` looks for via argument-dependent lookup. It only has an effect on fmt 10.0.0 through 11.0.2 — from fmt 11.1.0 onwards, `fmt` no longer picks up a `format_as` overload that returns a `std::string`. On such versions (or any version, if you also want the same `"{:#}"`/width/fill-and-align spec support that `std::formatter` has), define your own `fmt::formatter` specialization; see [`format_as`](https://json.nlohmann.me/api/basic_json/format_as/index.md) for a recipe that mirrors it. + +If you get ambiguous-overload errors when passing a JSON value to `fmt::format`/`fmt::print` without any `fmt::formatter` specialization in scope, that's `fmt` picking up `basic_json`'s implicit `operator ValueType()` conversion operator (see [#964](https://github.com/nlohmann/json/issues/964) and [#958](https://github.com/nlohmann/json/issues/958)); disabling it via [`JSON_USE_IMPLICIT_CONVERSIONS 0`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) avoids the ambiguity. + +## Compilation issues + +### Android SDK + +Question + +Why does the code not compile with Android SDK? + +Android defaults to using very old compilers and C++ libraries. To fix this, add the following to your `Application.mk`. This will switch to the LLVM C++ library, the Clang compiler, and enable C++11 and other features disabled by default. + +``` +APP_STL := c++_shared +NDK_TOOLCHAIN_VERSION := clang3.6 +APP_CPPFLAGS += -frtti -fexceptions +``` + +The code compiles successfully with [Android NDK](https://developer.android.com/ndk/index.html?hl=ml), Revision 9 - 11 (and possibly later) and [CrystaX's Android NDK](https://www.crystax.net/en/android/ndk) version 10. + +### Missing STL function + +Questions + +- Why do I get a compilation error `'to_string' is not a member of 'std'` (or similarly, for `strtod` or `strtof`)? +- Why does the code not compile with MinGW or Android SDK? + +This is not an issue with the code, but rather with the compiler itself. On Android, see above to build with a newer environment. For MinGW, please refer to [this site](http://tehsausage.com/mingw-to-string) and [this discussion](https://github.com/nlohmann/json/issues/136) for information on how to fix this bug. For Android NDK using `APP_STL := gnustl_static`, please refer to [this discussion](https://github.com/nlohmann/json/issues/219). diff --git a/home/license.md b/home/license.md new file mode 100644 index 000000000..597c69496 --- /dev/null +++ b/home/license.md @@ -0,0 +1,21 @@ +# License + + + +The class is licensed under the [MIT License](https://opensource.org/licenses/MIT): + +Copyright © 2013-2026 [Niels Lohmann](https://nlohmann.me) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +* * * + +The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2008-2009 [Björn Hoehrmann](http://bjoern.hoehrmann.de/) + +The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/) + +The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/home/license/index.html b/home/license/index.html index 264190ec0..ef4a48100 100644 --- a/home/license/index.html +++ b/home/license/index.html @@ -1 +1 @@ - License - JSON for Modern C++

    License

    The class is licensed under the MIT License:

    Copyright © 2013-2026 Niels Lohmann

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


    The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the MIT License (see above). Copyright © 2008-2009 Björn Hoehrmann bjoern@hoehrmann.de

    The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the MIT License (see above). Copyright © 2009 Florian Loitsch

    The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.

    \ No newline at end of file + License - JSON for Modern C++

    License

    The class is licensed under the MIT License:

    Copyright © 2013-2026 Niels Lohmann

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


    The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the MIT License (see above). Copyright © 2008-2009 Björn Hoehrmann bjoern@hoehrmann.de

    The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the MIT License (see above). Copyright © 2009 Florian Loitsch

    The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0.

    \ No newline at end of file diff --git a/home/license/index.md b/home/license/index.md new file mode 100644 index 000000000..962d600d8 --- /dev/null +++ b/home/license/index.md @@ -0,0 +1,19 @@ +# License + +The class is licensed under the [MIT License](https://opensource.org/licenses/MIT): + +Copyright © 2013-2026 [Niels Lohmann](https://nlohmann.me) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +______________________________________________________________________ + +The class contains the UTF-8 Decoder from Bjoern Hoehrmann which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2008-2009 [Björn Hoehrmann](http://bjoern.hoehrmann.de/) [bjoern@hoehrmann.de](mailto:bjoern@hoehrmann.de) + +The class contains a slightly modified version of the Grisu2 algorithm from Florian Loitsch which is licensed under the [MIT License](https://opensource.org/licenses/MIT) (see above). Copyright © 2009 [Florian Loitsch](https://florian.loitsch.com/) + +The class contains a copy of [Hedley](https://nemequ.github.io/hedley/) from Evan Nemerson which is licensed as [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/home/releases.md b/home/releases.md new file mode 100644 index 000000000..cdaca4c0d --- /dev/null +++ b/home/releases.md @@ -0,0 +1,439 @@ +# Releases + +This page summarizes the notable changes of every release and links to the relevant documentation. +The **complete release notes** — including all changes, the download files, and their checksums — are +published on the [GitHub releases page](https://github.com/nlohmann/json/releases). + +## v3.12.0 (2025-04-11) + +Fixes bugs found in 3.11.3 and adds several features. All changes are backward-compatible. + +- Adds diagnostic byte positions via [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md), + exposed through the new [`start_pos`](../api/basic_json/start_pos.md) and + [`end_pos`](../api/basic_json/end_pos.md) member functions. +- Makes the [conversion macros](../features/arbitrary_types.md#simplify-your-life-with-macros) + templated (so they also work with [`ordered_json`](../api/ordered_json.md)) and adds + [`NLOHMANN_DEFINE_DERIVED_TYPE`](../api/macros/nlohmann_define_derived_type.md) for derived classes. +- Adds `std::optional` support (C++17) and lets [`patch`](../api/basic_json/patch.md), + [`diff`](../api/basic_json/diff.md), and [`flatten`](../api/basic_json/flatten.md) work with + arbitrary string types. +- Extends the [binary formats](../features/binary_formats/index.md): + [BJData](../features/binary_formats/bjdata.md) draft 3 and unsigned 64-bit integers for + [BSON](../features/binary_formats/bson.md). +- Adds multidimensional C-array conversion and UTF-8 encoded `std::filesystem::path` conversions, and + lowers the minimum [CMake](../integration/cmake.md) version to allow CMake 4.0. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.12.0). + +## v3.11.3 (2023-11-28) + +Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible. + +- Adds a [custom base class](../api/basic_json/json_base_class_t.md) as a node customization point. +- Adds serialization-only [conversion macros](../features/macros.md) + (`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` and `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE`) + and a clearer parse error for empty input. +- Adds [Bazel](../integration/package_managers.md#bazel) and + [Swift Package Manager](../integration/package_managers.md#swift-package-manager) build support. +- Fixes custom allocators, a memory leak in [`adl_serializer`](../api/adl_serializer/to_json.md)'s + `to_json`, initializer-list construction when `size_type` is not `int`, and many compiler warnings. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.3). + +## v3.11.2 (2022-08-12) + +Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible. + +- Fixes the [`value`](../api/basic_json/value.md) function (broken for strings, size types, and + `nullptr` in 3.11.0) and makes `json_fwd.hpp` self-contained. +- Restores using [`json_pointer`](../api/json_pointer/index.md) as a key in associative containers and + comparing it with strings. +- Restructures the inline [namespace](../features/namespace.md) and allows disabling the version + component, and avoids heap allocations in the [BJData](../features/binary_formats/bjdata.md) parser. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.2). + +## v3.11.1 (2022-08-01) + +Fixes a regression from 3.11.0. All changes are backward-compatible. + +- Restores the global [user-defined string literals](../api/macros/json_use_global_udls.md) + [`operator""_json`](../api/operator_literal_json.md) and + [`operator""_json_pointer`](../api/operator_literal_json_pointer.md), which 3.11.0 had moved into a + namespace by default. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.1). + +## v3.11.0 (2022-08-01) + +One of the largest releases ever. All changes are backward-compatible. + +- Allows `std::string_view` as object keys in [`at`](../api/basic_json/at.md), + [`operator[]`](../api/basic_json/operator%5B%5D.md), [`value`](../api/basic_json/value.md), + [`erase`](../api/basic_json/erase.md), [`find`](../api/basic_json/find.md), + [`contains`](../api/basic_json/contains.md), and [`count`](../api/basic_json/count.md). +- Adds the [BJData](../features/binary_formats/bjdata.md) binary format (the fifth supported format). +- Improves C++20 support, including [`operator<=>`](../api/basic_json/operator_spaceship.md) and + ``-compatible iterators. +- Adds a versioned, ABI-tagged inline [namespace](../features/namespace.md) + ([`NLOHMANN_JSON_NAMESPACE`](../api/macros/nlohmann_json_namespace.md)) and the option to move the + UDLs out of the global namespace ([`JSON_USE_GLOBAL_UDLS`](../api/macros/json_use_global_udls.md)). +- Adds [`patch_inplace`](../api/basic_json/patch_inplace.md), default values for the + [conversion macros](../features/arbitrary_types.md#simplify-your-life-with-macros), and an option to + disable enum serialization ([`JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md)). + +This release introduced a UDL regression that was fixed in +[3.11.1](https://github.com/nlohmann/json/releases/tag/v3.11.1). +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.0). + +## v3.10.5 (2022-01-03) + +Bug-fix release. All changes are backward-compatible. + +- Guards the `std::filesystem` conversions behind compiler-support checks + ([`JSON_HAS_FILESYSTEM`](../api/macros/json_has_filesystem.md)), which can be set to `0` to disable + them altogether. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.5). + +## v3.10.4 (2021-10-16) + +Fixes regressions introduced in 3.10.0. All changes are backward-compatible. + +- Fixes the `std::filesystem::path` conversion (which could trigger a stack overflow and broke + compilation on Windows). +- Fixes compilation for types with an explicit defaulted constructor and for code relying on the + return values of `std::find` and `std::remove`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.4). + +## v3.10.3 (2021-10-08) + +Fixes more regressions from 3.10.0. All changes are backward-compatible. + +- Fixes [extended-diagnostics](../api/macros/json_diagnostics.md) assertions triggered by + [`update`](../api/basic_json/update.md) and by inserting into arrays. +- Supports custom allocators when writing binary formats into a `std::vector`, and allows conversion + from types that only provide `begin()`/`end()`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.3). + +## v3.10.2 (2021-08-26) + +Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. +All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.2). + +## v3.10.1 (2021-08-24) + +Fixes a regression from 3.10.0. All changes are backward-compatible. + +- Fixes an [extended-diagnostics](../api/macros/json_diagnostics.md) assertion triggered when used + with [`ordered_json`](../api/ordered_json.md), and hardens the GDB pretty-printer. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.1). + +## v3.10.0 (2021-08-17) + +Feature release. All changes are backward-compatible. + +- Adds [extended diagnostic messages](../api/macros/json_diagnostics.md) + ([`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md)) that prepend a JSON pointer to exception + messages to pinpoint the offending value. +- Adds a GDB pretty-printer and a [`cbor_tag_handler_t`](../api/basic_json/cbor_tag_handler_t.md) + `store` option to keep CBOR tags as binary subtypes. +- Supports containers with non-default-constructible types and parsing from `std::byte`. +- Adds [`JSON_NO_IO`](../api/macros/json_no_io.md) to exclude the I/O headers and the + [`JSON_HAS_CPP_*`](../api/macros/json_has_cpp_11.md) macros to override the detected C++ standard. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.0). + +## v3.9.1 (2020-08-06) + +Fixes two regressions from 3.9.0. All changes are backward-compatible. + +- Accepts consecutive [comments](../features/comments.md) and completes the + [`ordered_json`](../api/ordered_json.md) interface (e.g. `ordered_json::parse`). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.9.1). + +## v3.9.0 (2020-07-27) + +Feature release adding four long-requested features. All changes are backward-compatible. + +- Optional [comment](../features/comments.md) parsing in [`parse`](../api/basic_json/parse.md) via the + `ignore_comments` parameter. +- [`ordered_json`](../api/ordered_json.md) to preserve the [insertion order](../features/object_order.md) + of object keys. +- An option to switch off [implicit conversions](../api/macros/json_use_implicit_conversions.md). +- The [`NLOHMANN_DEFINE_TYPE_*`](../features/arbitrary_types.md#simplify-your-life-with-macros) + convenience macros, plus high-precision-number support for + [UBJSON](../features/binary_formats/ubjson.md) and CBOR tag handling. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.9.0). + +## v3.8.0 (2020-06-14) + +Feature release. All changes are backward-compatible. + +- Introduces a [binary value](../features/binary_values.md) type that is read from and written to + [CBOR](../features/binary_formats/cbor.md), [BSON](../features/binary_formats/bson.md), and + [MessagePack](../features/binary_formats/messagepack.md), and can be shared between formats. +- Generalizes the input adapters to read from any `LegacyInputIterator` container (3–10 % faster + parsing). +- Fixes [`contains`](../api/basic_json/contains.md) for JSON pointers and makes the binary + [`from_cbor`](../api/basic_json/from_cbor.md)/[`from_msgpack`](../api/basic_json/from_msgpack.md)/etc. + functions respect `allow_exceptions`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.8.0). + +## v3.7.3 (2019-11-17) + +Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes +are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.3). + +## v3.7.2 (2019-11-10) + +Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing is now +bounded only by available memory. All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.2). + +## v3.7.1 (2019-11-06) + +Bug-fix release. All changes are backward-compatible. + +- Fixes a segmentation fault when serializing the `std::int64_t` minimum value and fixes + [`contains`](../api/basic_json/contains.md) for JSON pointers. +- Allows [`items`](../api/basic_json/items.md) with a custom string type and makes `json_pointer::back` + `const`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.1). + +## v3.7.0 (2019-07-28) + +Convenience features and house-keeping. All changes are backward-compatible. + +- Adds a [`contains`](../api/basic_json/contains.md) overload that checks a JSON pointer without + throwing, a generic `to_string`, and a return value for + [`emplace_back`](../api/basic_json/emplace_back.md). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.0). + +## v3.6.1 (2019-03-20) + +Fixes a regression (GCC 7/8 compilation) and a `` build error introduced in 3.6.0. All +changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.6.1). + +## v3.6.0 (2019-03-20) + +Feature release. All changes are backward-compatible. + +- Reworks the [JSON pointer](../features/json_pointer.md) interface (`operator/`, `push_back`, + `parent_pointer`, …). +- Adds a [`contains`](../api/basic_json/contains.md) function to test for an object key and greatly + improves the performance of integer serialization. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.6.0). + +## v3.5.0 (2018-12-22) + +Feature release. All changes are backward-compatible. + +- Adds structured-binding support via the [`items`](../api/basic_json/items.md) function and reading + from `FILE*` in the [`parse`](../api/basic_json/parse.md) function. +- Fixes the `eofbit` handling on input streams and a bug in the BSON SAX parser. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.5.0). + +## v3.4.0 (2018-10-30) + +Feature release. All changes are backward-compatible. + +- Adds [BSON](../features/binary_formats/bson.md) read/write support. +- Adds configurable Unicode error handlers to [`dump`](../api/basic_json/dump.md) (throw, replace with + U+FFFD, or ignore) and the + [`NLOHMANN_JSON_SERIALIZE_ENUM`](../api/macros/nlohmann_json_serialize_enum.md) macro for + [enum conversion](../features/enum_conversion.md). +- Improves parse-error messages with line/column positions and context. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.4.0). + +## v3.3.0 (2018-10-05) + +Feature release. All changes are backward-compatible. + +- Adds GCC 4.8 support, the [`get_to`](../api/basic_json/get_to.md) function, and an overhauled and + documented [CMake](../integration/cmake.md) integration. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.3.0). + +## v3.2.0 (2018-08-20) + +Feature release. All changes are backward-compatible. + +- Adds a [SAX interface](../features/parsing/sax_interface.md) and a non-recursive parser. +- Adds parsing from wide-string types (`std::wstring`, `std::u16string`, `std::u32string`) and + `std::string_view` (C++17), and round-tripping of `std::map`/`std::unordered_map` with non-string + keys. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.2.0). + +## v3.1.2 (2018-03-14) + +Bug-fix release. All changes are backward-compatible. + +- Fixes a memory leak in the parser callback and adds user-defined string-type support to the parser + and serializer. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.1.2). + +## v3.1.1 (2018-02-13) + +Bug-fix release. All changes are backward-compatible. + +- Fixes parsing of indefinite-length CBOR strings, a user-defined conversion to vector types, and + overflow detection for UBJSON containers. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.1.1). + +## v3.1.0 (2018-02-01) + +Feature release. All changes are backward-compatible. + +- Adds [UBJSON](../features/binary_formats/ubjson.md) read/write support and + [JSON Merge Patch](../features/merge_patch.md) via [`merge_patch`](../api/basic_json/merge_patch.md). +- Switches to the Grisu2 algorithm for short, round-trippable floating-point output, and splits the + header into [multiple files](../integration/index.md) with a forward-declaration header. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.1.0). + +## v3.0.1 (2017-12-29) + +Fixes small issues in the [JSON Pointer](../features/json_pointer.md) and +[JSON Patch](../features/json_patch.md) implementations (invalid "copy" targets and non-integer array +indices). All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.0.1). + +## v3.0.0 (2017-12-17) + +First 3.x release — a major release with breaking changes (see the +[migration guide](../integration/migration_guide.md)). + +- Introduces user-defined [exceptions](exceptions.md) (`json::exception` and subtypes, each with an + identifier). +- Adds a non-throwing [`accept`](../api/basic_json/accept.md) function and an `allow_exceptions` flag + for [`parse`](../api/basic_json/parse.md), and an [`update`](../api/basic_json/update.md) function to + merge objects. +- Adds streaming for CBOR and MessagePack and allows storing NaN/infinity. +- Non-UTF-8 strings now throw on serialization, and the iterator category changed to bidirectional. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.0.0). + +## v2.1.1 (2017-02-25) + +Bug-fix release. All changes are backward-compatible. + +- Makes number parsing and serialization locale-independent with correct floating-point + round-tripping; released files are now GPG-signed. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.1.1). + +## v2.1.0 (2017-01-28) + +Feature release. All changes are backward-compatible. + +- Adds conversions from and to [arbitrary user-defined types](../features/arbitrary_types.md) via + `to_json`/`from_json`, the [`meta`](../api/basic_json/meta.md) function, and the option to switch off + exceptions ([`JSON_NOEXCEPTION`](../api/macros/json_noexception.md)). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.1.0). + +## v2.0.10 (2017-01-02) + +Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All +changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.10). + +## v2.0.9 (2016-12-16) + +Adds the [CBOR](../features/binary_formats/cbor.md) and +[MessagePack](../features/binary_formats/messagepack.md) binary formats. All changes are +backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.9). + +## v2.0.8 (2016-12-02) + +Adds the [`emplace`](../api/basic_json/emplace.md) and +[`emplace_back`](../api/basic_json/emplace_back.md) functions and improves parsing and serialization +performance. All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.8). + +## v2.0.7 (2016-11-02) + +Fixes several parser bugs found through the "Parsing JSON is a Minefield" study (short files, encoding +detection, surrogate pairs). All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.7). + +## v2.0.6 (2016-10-15) + +Fixes [`operator[]`](../api/basic_json/operator%5B%5D.md) for [JSON pointers](../features/json_pointer.md) +so that it creates missing values like the other overloads. All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.6). + +## v2.0.5 (2016-09-14) + +Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.5). + +## v2.0.4 (2016-09-11) + +Fixes stream end-of-file detection in the parser. All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.4). + +## v2.0.3 (2016-08-31) + +Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the +input-stream constructor in favor of the [`parse`](../api/basic_json/parse.md) function. All changes +are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.3). + +## v2.0.2 (2016-07-31) + +Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and +cleans up the code. All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.2). + +## v2.0.1 (2016-06-28) + +Fixes a performance regression in the [`dump`](../api/basic_json/dump.md) function by adjusting the +stream locale once per serialization. All changes are backward-compatible. +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.1). + +## v2.0.0 (2016-06-24) + +Feature release with a minor (potentially non-backward-compatible) API change from added `noexcept` +and `constexpr` specifiers. + +- Adds [JSON Pointer](../features/json_pointer.md) support in [`at`](../api/basic_json/at.md) and + [`operator[]`](../api/basic_json/operator%5B%5D.md), plus [`flatten`](../api/basic_json/flatten.md) + and [`unflatten`](../api/basic_json/unflatten.md). +- Adds [JSON Patch](../features/json_patch.md) via [`diff`](../api/basic_json/diff.md) and + [`patch`](../api/basic_json/patch.md), unsigned 64-bit integer support, and locale-independent + serialization. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.0). + +## v1.1.0 (2016-01-24) + +Bug-fix and feature release. All changes are backward-compatible. + +- Improves floating-point round-tripping, adds a `get_ref` accessor for stored values, and introduces + runtime [assertions](../features/assertions.md). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v1.1.0). + +## v1.0.0 (2015-12-28) + +First official release. [Full release notes](https://github.com/nlohmann/json/releases/tag/v1.0.0). + +## See also + +- [Migration Guide](../integration/migration_guide.md) — how to future-proof your code for the next + major version and replace deprecated functions. diff --git a/home/releases/index.html b/home/releases/index.html index 985fd6fda..b0a4f006e 100644 --- a/home/releases/index.html +++ b/home/releases/index.html @@ -1 +1 @@ - Releases - JSON for Modern C++

    Releases

    This page summarizes the notable changes of every release and links to the relevant documentation. The complete release notes — including all changes, the download files, and their checksums — are published on the GitHub releases page.

    v3.12.0 (2025-04-11)

    Fixes bugs found in 3.11.3 and adds several features. All changes are backward-compatible.

    Full release notes.

    v3.11.3 (2023-11-28)

    Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible.

    • Adds a custom base class as a node customization point.
    • Adds serialization-only conversion macros (NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE) and a clearer parse error for empty input.
    • Adds Bazel and Swift Package Manager build support.
    • Fixes custom allocators, a memory leak in adl_serializer's to_json, initializer-list construction when size_type is not int, and many compiler warnings.

    Full release notes.

    v3.11.2 (2022-08-12)

    Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible.

    • Fixes the value function (broken for strings, size types, and nullptr in 3.11.0) and makes json_fwd.hpp self-contained.
    • Restores using json_pointer as a key in associative containers and comparing it with strings.
    • Restructures the inline namespace and allows disabling the version component, and avoids heap allocations in the BJData parser.

    Full release notes.

    v3.11.1 (2022-08-01)

    Fixes a regression from 3.11.0. All changes are backward-compatible.

    Full release notes.

    v3.11.0 (2022-08-01)

    One of the largest releases ever. All changes are backward-compatible.

    This release introduced a UDL regression that was fixed in 3.11.1. Full release notes.

    v3.10.5 (2022-01-03)

    Bug-fix release. All changes are backward-compatible.

    • Guards the std::filesystem conversions behind compiler-support checks (JSON_HAS_FILESYSTEM), which can be set to 0 to disable them altogether.

    Full release notes.

    v3.10.4 (2021-10-16)

    Fixes regressions introduced in 3.10.0. All changes are backward-compatible.

    • Fixes the std::filesystem::path conversion (which could trigger a stack overflow and broke compilation on Windows).
    • Fixes compilation for types with an explicit defaulted constructor and for code relying on the return values of std::find and std::remove.

    Full release notes.

    v3.10.3 (2021-10-08)

    Fixes more regressions from 3.10.0. All changes are backward-compatible.

    • Fixes extended-diagnostics assertions triggered by update and by inserting into arrays.
    • Supports custom allocators when writing binary formats into a std::vector, and allows conversion from types that only provide begin()/end().

    Full release notes.

    v3.10.2 (2021-08-26)

    Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. All changes are backward-compatible. Full release notes.

    v3.10.1 (2021-08-24)

    Fixes a regression from 3.10.0. All changes are backward-compatible.

    Full release notes.

    v3.10.0 (2021-08-17)

    Feature release. All changes are backward-compatible.

    • Adds extended diagnostic messages (JSON_DIAGNOSTICS) that prepend a JSON pointer to exception messages to pinpoint the offending value.
    • Adds a GDB pretty-printer and a cbor_tag_handler_t store option to keep CBOR tags as binary subtypes.
    • Supports containers with non-default-constructible types and parsing from std::byte.
    • Adds JSON_NO_IO to exclude the I/O headers and the JSON_HAS_CPP_* macros to override the detected C++ standard.

    Full release notes.

    v3.9.1 (2020-08-06)

    Fixes two regressions from 3.9.0. All changes are backward-compatible.

    Full release notes.

    v3.9.0 (2020-07-27)

    Feature release adding four long-requested features. All changes are backward-compatible.

    Full release notes.

    v3.8.0 (2020-06-14)

    Feature release. All changes are backward-compatible.

    • Introduces a binary value type that is read from and written to CBOR, BSON, and MessagePack, and can be shared between formats.
    • Generalizes the input adapters to read from any LegacyInputIterator container (3–10 % faster parsing).
    • Fixes contains for JSON pointers and makes the binary from_cbor/from_msgpack/etc. functions respect allow_exceptions.

    Full release notes.

    v3.7.3 (2019-11-17)

    Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes are backward-compatible. Full release notes.

    v3.7.2 (2019-11-10)

    Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing is now bounded only by available memory. All changes are backward-compatible. Full release notes.

    v3.7.1 (2019-11-06)

    Bug-fix release. All changes are backward-compatible.

    • Fixes a segmentation fault when serializing the std::int64_t minimum value and fixes contains for JSON pointers.
    • Allows items with a custom string type and makes json_pointer::back const.

    Full release notes.

    v3.7.0 (2019-07-28)

    Convenience features and house-keeping. All changes are backward-compatible.

    • Adds a contains overload that checks a JSON pointer without throwing, a generic to_string, and a return value for emplace_back.

    Full release notes.

    v3.6.1 (2019-03-20)

    Fixes a regression (GCC 7/8 compilation) and a <Windows.h> build error introduced in 3.6.0. All changes are backward-compatible. Full release notes.

    v3.6.0 (2019-03-20)

    Feature release. All changes are backward-compatible.

    • Reworks the JSON pointer interface (operator/, push_back, parent_pointer, …).
    • Adds a contains function to test for an object key and greatly improves the performance of integer serialization.

    Full release notes.

    v3.5.0 (2018-12-22)

    Feature release. All changes are backward-compatible.

    • Adds structured-binding support via the items function and reading from FILE* in the parse function.
    • Fixes the eofbit handling on input streams and a bug in the BSON SAX parser.

    Full release notes.

    v3.4.0 (2018-10-30)

    Feature release. All changes are backward-compatible.

    Full release notes.

    v3.3.0 (2018-10-05)

    Feature release. All changes are backward-compatible.

    • Adds GCC 4.8 support, the get_to function, and an overhauled and documented CMake integration.

    Full release notes.

    v3.2.0 (2018-08-20)

    Feature release. All changes are backward-compatible.

    • Adds a SAX interface and a non-recursive parser.
    • Adds parsing from wide-string types (std::wstring, std::u16string, std::u32string) and std::string_view (C++17), and round-tripping of std::map/std::unordered_map with non-string keys.

    Full release notes.

    v3.1.2 (2018-03-14)

    Bug-fix release. All changes are backward-compatible.

    • Fixes a memory leak in the parser callback and adds user-defined string-type support to the parser and serializer.

    Full release notes.

    v3.1.1 (2018-02-13)

    Bug-fix release. All changes are backward-compatible.

    • Fixes parsing of indefinite-length CBOR strings, a user-defined conversion to vector types, and overflow detection for UBJSON containers.

    Full release notes.

    v3.1.0 (2018-02-01)

    Feature release. All changes are backward-compatible.

    Full release notes.

    v3.0.1 (2017-12-29)

    Fixes small issues in the JSON Pointer and JSON Patch implementations (invalid "copy" targets and non-integer array indices). All changes are backward-compatible. Full release notes.

    v3.0.0 (2017-12-17)

    First 3.x release — a major release with breaking changes (see the migration guide).

    • Introduces user-defined exceptions (json::exception and subtypes, each with an identifier).
    • Adds a non-throwing accept function and an allow_exceptions flag for parse, and an update function to merge objects.
    • Adds streaming for CBOR and MessagePack and allows storing NaN/infinity.
    • Non-UTF-8 strings now throw on serialization, and the iterator category changed to bidirectional.

    Full release notes.

    v2.1.1 (2017-02-25)

    Bug-fix release. All changes are backward-compatible.

    • Makes number parsing and serialization locale-independent with correct floating-point round-tripping; released files are now GPG-signed.

    Full release notes.

    v2.1.0 (2017-01-28)

    Feature release. All changes are backward-compatible.

    Full release notes.

    v2.0.10 (2017-01-02)

    Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All changes are backward-compatible. Full release notes.

    v2.0.9 (2016-12-16)

    Adds the CBOR and MessagePack binary formats. All changes are backward-compatible. Full release notes.

    v2.0.8 (2016-12-02)

    Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Full release notes.

    v2.0.7 (2016-11-02)

    Fixes several parser bugs found through the "Parsing JSON is a Minefield" study (short files, encoding detection, surrogate pairs). All changes are backward-compatible. Full release notes.

    v2.0.6 (2016-10-15)

    Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Full release notes.

    v2.0.5 (2016-09-14)

    Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. Full release notes.

    v2.0.4 (2016-09-11)

    Fixes stream end-of-file detection in the parser. All changes are backward-compatible. Full release notes.

    v2.0.3 (2016-08-31)

    Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the input-stream constructor in favor of the parse function. All changes are backward-compatible. Full release notes.

    v2.0.2 (2016-07-31)

    Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and cleans up the code. All changes are backward-compatible. Full release notes.

    v2.0.1 (2016-06-28)

    Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Full release notes.

    v2.0.0 (2016-06-24)

    Feature release with a minor (potentially non-backward-compatible) API change from added noexcept and constexpr specifiers.

    Full release notes.

    v1.1.0 (2016-01-24)

    Bug-fix and feature release. All changes are backward-compatible.

    • Improves floating-point round-tripping, adds a get_ref accessor for stored values, and introduces runtime assertions.

    Full release notes.

    v1.0.0 (2015-12-28)

    First official release. Full release notes.

    See also

    • Migration Guide — how to future-proof your code for the next major version and replace deprecated functions.
    \ No newline at end of file + Releases - JSON for Modern C++

    Releases

    This page summarizes the notable changes of every release and links to the relevant documentation. The complete release notes — including all changes, the download files, and their checksums — are published on the GitHub releases page.

    v3.12.0 (2025-04-11)

    Fixes bugs found in 3.11.3 and adds several features. All changes are backward-compatible.

    Full release notes.

    v3.11.3 (2023-11-28)

    Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible.

    • Adds a custom base class as a node customization point.
    • Adds serialization-only conversion macros (NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE and NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE) and a clearer parse error for empty input.
    • Adds Bazel and Swift Package Manager build support.
    • Fixes custom allocators, a memory leak in adl_serializer's to_json, initializer-list construction when size_type is not int, and many compiler warnings.

    Full release notes.

    v3.11.2 (2022-08-12)

    Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible.

    • Fixes the value function (broken for strings, size types, and nullptr in 3.11.0) and makes json_fwd.hpp self-contained.
    • Restores using json_pointer as a key in associative containers and comparing it with strings.
    • Restructures the inline namespace and allows disabling the version component, and avoids heap allocations in the BJData parser.

    Full release notes.

    v3.11.1 (2022-08-01)

    Fixes a regression from 3.11.0. All changes are backward-compatible.

    Full release notes.

    v3.11.0 (2022-08-01)

    One of the largest releases ever. All changes are backward-compatible.

    This release introduced a UDL regression that was fixed in 3.11.1. Full release notes.

    v3.10.5 (2022-01-03)

    Bug-fix release. All changes are backward-compatible.

    • Guards the std::filesystem conversions behind compiler-support checks (JSON_HAS_FILESYSTEM), which can be set to 0 to disable them altogether.

    Full release notes.

    v3.10.4 (2021-10-16)

    Fixes regressions introduced in 3.10.0. All changes are backward-compatible.

    • Fixes the std::filesystem::path conversion (which could trigger a stack overflow and broke compilation on Windows).
    • Fixes compilation for types with an explicit defaulted constructor and for code relying on the return values of std::find and std::remove.

    Full release notes.

    v3.10.3 (2021-10-08)

    Fixes more regressions from 3.10.0. All changes are backward-compatible.

    • Fixes extended-diagnostics assertions triggered by update and by inserting into arrays.
    • Supports custom allocators when writing binary formats into a std::vector, and allows conversion from types that only provide begin()/end().

    Full release notes.

    v3.10.2 (2021-08-26)

    Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. All changes are backward-compatible. Full release notes.

    v3.10.1 (2021-08-24)

    Fixes a regression from 3.10.0. All changes are backward-compatible.

    Full release notes.

    v3.10.0 (2021-08-17)

    Feature release. All changes are backward-compatible.

    • Adds extended diagnostic messages (JSON_DIAGNOSTICS) that prepend a JSON pointer to exception messages to pinpoint the offending value.
    • Adds a GDB pretty-printer and a cbor_tag_handler_t store option to keep CBOR tags as binary subtypes.
    • Supports containers with non-default-constructible types and parsing from std::byte.
    • Adds JSON_NO_IO to exclude the I/O headers and the JSON_HAS_CPP_* macros to override the detected C++ standard.

    Full release notes.

    v3.9.1 (2020-08-06)

    Fixes two regressions from 3.9.0. All changes are backward-compatible.

    Full release notes.

    v3.9.0 (2020-07-27)

    Feature release adding four long-requested features. All changes are backward-compatible.

    Full release notes.

    v3.8.0 (2020-06-14)

    Feature release. All changes are backward-compatible.

    • Introduces a binary value type that is read from and written to CBOR, BSON, and MessagePack, and can be shared between formats.
    • Generalizes the input adapters to read from any LegacyInputIterator container (3–10 % faster parsing).
    • Fixes contains for JSON pointers and makes the binary from_cbor/from_msgpack/etc. functions respect allow_exceptions.

    Full release notes.

    v3.7.3 (2019-11-17)

    Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes are backward-compatible. Full release notes.

    v3.7.2 (2019-11-10)

    Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing is now bounded only by available memory. All changes are backward-compatible. Full release notes.

    v3.7.1 (2019-11-06)

    Bug-fix release. All changes are backward-compatible.

    • Fixes a segmentation fault when serializing the std::int64_t minimum value and fixes contains for JSON pointers.
    • Allows items with a custom string type and makes json_pointer::back const.

    Full release notes.

    v3.7.0 (2019-07-28)

    Convenience features and house-keeping. All changes are backward-compatible.

    • Adds a contains overload that checks a JSON pointer without throwing, a generic to_string, and a return value for emplace_back.

    Full release notes.

    v3.6.1 (2019-03-20)

    Fixes a regression (GCC 7/8 compilation) and a <Windows.h> build error introduced in 3.6.0. All changes are backward-compatible. Full release notes.

    v3.6.0 (2019-03-20)

    Feature release. All changes are backward-compatible.

    • Reworks the JSON pointer interface (operator/, push_back, parent_pointer, …).
    • Adds a contains function to test for an object key and greatly improves the performance of integer serialization.

    Full release notes.

    v3.5.0 (2018-12-22)

    Feature release. All changes are backward-compatible.

    • Adds structured-binding support via the items function and reading from FILE* in the parse function.
    • Fixes the eofbit handling on input streams and a bug in the BSON SAX parser.

    Full release notes.

    v3.4.0 (2018-10-30)

    Feature release. All changes are backward-compatible.

    Full release notes.

    v3.3.0 (2018-10-05)

    Feature release. All changes are backward-compatible.

    • Adds GCC 4.8 support, the get_to function, and an overhauled and documented CMake integration.

    Full release notes.

    v3.2.0 (2018-08-20)

    Feature release. All changes are backward-compatible.

    • Adds a SAX interface and a non-recursive parser.
    • Adds parsing from wide-string types (std::wstring, std::u16string, std::u32string) and std::string_view (C++17), and round-tripping of std::map/std::unordered_map with non-string keys.

    Full release notes.

    v3.1.2 (2018-03-14)

    Bug-fix release. All changes are backward-compatible.

    • Fixes a memory leak in the parser callback and adds user-defined string-type support to the parser and serializer.

    Full release notes.

    v3.1.1 (2018-02-13)

    Bug-fix release. All changes are backward-compatible.

    • Fixes parsing of indefinite-length CBOR strings, a user-defined conversion to vector types, and overflow detection for UBJSON containers.

    Full release notes.

    v3.1.0 (2018-02-01)

    Feature release. All changes are backward-compatible.

    Full release notes.

    v3.0.1 (2017-12-29)

    Fixes small issues in the JSON Pointer and JSON Patch implementations (invalid "copy" targets and non-integer array indices). All changes are backward-compatible. Full release notes.

    v3.0.0 (2017-12-17)

    First 3.x release — a major release with breaking changes (see the migration guide).

    • Introduces user-defined exceptions (json::exception and subtypes, each with an identifier).
    • Adds a non-throwing accept function and an allow_exceptions flag for parse, and an update function to merge objects.
    • Adds streaming for CBOR and MessagePack and allows storing NaN/infinity.
    • Non-UTF-8 strings now throw on serialization, and the iterator category changed to bidirectional.

    Full release notes.

    v2.1.1 (2017-02-25)

    Bug-fix release. All changes are backward-compatible.

    • Makes number parsing and serialization locale-independent with correct floating-point round-tripping; released files are now GPG-signed.

    Full release notes.

    v2.1.0 (2017-01-28)

    Feature release. All changes are backward-compatible.

    Full release notes.

    v2.0.10 (2017-01-02)

    Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All changes are backward-compatible. Full release notes.

    v2.0.9 (2016-12-16)

    Adds the CBOR and MessagePack binary formats. All changes are backward-compatible. Full release notes.

    v2.0.8 (2016-12-02)

    Adds the emplace and emplace_back functions and improves parsing and serialization performance. All changes are backward-compatible. Full release notes.

    v2.0.7 (2016-11-02)

    Fixes several parser bugs found through the "Parsing JSON is a Minefield" study (short files, encoding detection, surrogate pairs). All changes are backward-compatible. Full release notes.

    v2.0.6 (2016-10-15)

    Fixes operator[] for JSON pointers so that it creates missing values like the other overloads. All changes are backward-compatible. Full release notes.

    v2.0.5 (2016-09-14)

    Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. Full release notes.

    v2.0.4 (2016-09-11)

    Fixes stream end-of-file detection in the parser. All changes are backward-compatible. Full release notes.

    v2.0.3 (2016-08-31)

    Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the input-stream constructor in favor of the parse function. All changes are backward-compatible. Full release notes.

    v2.0.2 (2016-07-31)

    Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and cleans up the code. All changes are backward-compatible. Full release notes.

    v2.0.1 (2016-06-28)

    Fixes a performance regression in the dump function by adjusting the stream locale once per serialization. All changes are backward-compatible. Full release notes.

    v2.0.0 (2016-06-24)

    Feature release with a minor (potentially non-backward-compatible) API change from added noexcept and constexpr specifiers.

    Full release notes.

    v1.1.0 (2016-01-24)

    Bug-fix and feature release. All changes are backward-compatible.

    • Improves floating-point round-tripping, adds a get_ref accessor for stored values, and introduces runtime assertions.

    Full release notes.

    v1.0.0 (2015-12-28)

    First official release. Full release notes.

    See also

    • Migration Guide — how to future-proof your code for the next major version and replace deprecated functions.
    \ No newline at end of file diff --git a/home/releases/index.md b/home/releases/index.md new file mode 100644 index 000000000..450f511a7 --- /dev/null +++ b/home/releases/index.md @@ -0,0 +1,329 @@ +# Releases + +This page summarizes the notable changes of every release and links to the relevant documentation. The **complete release notes** — including all changes, the download files, and their checksums — are published on the [GitHub releases page](https://github.com/nlohmann/json/releases). + +## v3.12.0 (2025-04-11) + +Fixes bugs found in 3.11.3 and adds several features. All changes are backward-compatible. + +- Adds diagnostic byte positions via [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md), exposed through the new [`start_pos`](https://json.nlohmann.me/api/basic_json/start_pos/index.md) and [`end_pos`](https://json.nlohmann.me/api/basic_json/end_pos/index.md) member functions. +- Makes the [conversion macros](https://json.nlohmann.me/features/arbitrary_types/#simplify-your-life-with-macros) templated (so they also work with [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md)) and adds [`NLOHMANN_DEFINE_DERIVED_TYPE`](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) for derived classes. +- Adds `std::optional` support (C++17) and lets [`patch`](https://json.nlohmann.me/api/basic_json/patch/index.md), [`diff`](https://json.nlohmann.me/api/basic_json/diff/index.md), and [`flatten`](https://json.nlohmann.me/api/basic_json/flatten/index.md) work with arbitrary string types. +- Extends the [binary formats](https://json.nlohmann.me/features/binary_formats/index.md): [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md) draft 3 and unsigned 64-bit integers for [BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md). +- Adds multidimensional C-array conversion and UTF-8 encoded `std::filesystem::path` conversions, and lowers the minimum [CMake](https://json.nlohmann.me/integration/cmake/index.md) version to allow CMake 4.0. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.12.0). + +## v3.11.3 (2023-11-28) + +Adds features and fixes bugs found in 3.11.2. All changes are backward-compatible. + +- Adds a [custom base class](https://json.nlohmann.me/api/basic_json/json_base_class_t/index.md) as a node customization point. +- Adds serialization-only [conversion macros](https://json.nlohmann.me/features/macros/index.md) (`NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE` and `NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE`) and a clearer parse error for empty input. +- Adds [Bazel](https://json.nlohmann.me/integration/package_managers/#bazel) and [Swift Package Manager](https://json.nlohmann.me/integration/package_managers/#swift-package-manager) build support. +- Fixes custom allocators, a memory leak in [`adl_serializer`](https://json.nlohmann.me/api/adl_serializer/to_json/index.md)'s `to_json`, initializer-list construction when `size_type` is not `int`, and many compiler warnings. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.3). + +## v3.11.2 (2022-08-12) + +Fixes bugs found in 3.11.1 and restructures the namespace. All changes are backward-compatible. + +- Fixes the [`value`](https://json.nlohmann.me/api/basic_json/value/index.md) function (broken for strings, size types, and `nullptr` in 3.11.0) and makes `json_fwd.hpp` self-contained. +- Restores using [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) as a key in associative containers and comparing it with strings. +- Restructures the inline [namespace](https://json.nlohmann.me/features/namespace/index.md) and allows disabling the version component, and avoids heap allocations in the [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md) parser. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.2). + +## v3.11.1 (2022-08-01) + +Fixes a regression from 3.11.0. All changes are backward-compatible. + +- Restores the global [user-defined string literals](https://json.nlohmann.me/api/macros/json_use_global_udls/index.md) [`operator""_json`](https://json.nlohmann.me/api/operator_literal_json/index.md) and [`operator""_json_pointer`](https://json.nlohmann.me/api/operator_literal_json_pointer/index.md), which 3.11.0 had moved into a namespace by default. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.1). + +## v3.11.0 (2022-08-01) + +One of the largest releases ever. All changes are backward-compatible. + +- Allows `std::string_view` as object keys in [`at`](https://json.nlohmann.me/api/basic_json/at/index.md), [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md), [`value`](https://json.nlohmann.me/api/basic_json/value/index.md), [`erase`](https://json.nlohmann.me/api/basic_json/erase/index.md), [`find`](https://json.nlohmann.me/api/basic_json/find/index.md), [`contains`](https://json.nlohmann.me/api/basic_json/contains/index.md), and [`count`](https://json.nlohmann.me/api/basic_json/count/index.md). +- Adds the [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md) binary format (the fifth supported format). +- Improves C++20 support, including [`operator<=>`](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) and ``-compatible iterators. +- Adds a versioned, ABI-tagged inline [namespace](https://json.nlohmann.me/features/namespace/index.md) ([`NLOHMANN_JSON_NAMESPACE`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace/index.md)) and the option to move the UDLs out of the global namespace ([`JSON_USE_GLOBAL_UDLS`](https://json.nlohmann.me/api/macros/json_use_global_udls/index.md)). +- Adds [`patch_inplace`](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md), default values for the [conversion macros](https://json.nlohmann.me/features/arbitrary_types/#simplify-your-life-with-macros), and an option to disable enum serialization ([`JSON_DISABLE_ENUM_SERIALIZATION`](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md)). + +This release introduced a UDL regression that was fixed in [3.11.1](https://github.com/nlohmann/json/releases/tag/v3.11.1). [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.11.0). + +## v3.10.5 (2022-01-03) + +Bug-fix release. All changes are backward-compatible. + +- Guards the `std::filesystem` conversions behind compiler-support checks ([`JSON_HAS_FILESYSTEM`](https://json.nlohmann.me/api/macros/json_has_filesystem/index.md)), which can be set to `0` to disable them altogether. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.5). + +## v3.10.4 (2021-10-16) + +Fixes regressions introduced in 3.10.0. All changes are backward-compatible. + +- Fixes the `std::filesystem::path` conversion (which could trigger a stack overflow and broke compilation on Windows). +- Fixes compilation for types with an explicit defaulted constructor and for code relying on the return values of `std::find` and `std::remove`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.4). + +## v3.10.3 (2021-10-08) + +Fixes more regressions from 3.10.0. All changes are backward-compatible. + +- Fixes [extended-diagnostics](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) assertions triggered by [`update`](https://json.nlohmann.me/api/basic_json/update/index.md) and by inserting into arrays. +- Supports custom allocators when writing binary formats into a `std::vector`, and allows conversion from types that only provide `begin()`/`end()`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.3). + +## v3.10.2 (2021-08-26) + +Re-release of 3.10.1, whose Git tag pointed at the wrong commit due to a bug in the release script. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.2). + +## v3.10.1 (2021-08-24) + +Fixes a regression from 3.10.0. All changes are backward-compatible. + +- Fixes an [extended-diagnostics](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) assertion triggered when used with [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md), and hardens the GDB pretty-printer. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.1). + +## v3.10.0 (2021-08-17) + +Feature release. All changes are backward-compatible. + +- Adds [extended diagnostic messages](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) ([`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md)) that prepend a JSON pointer to exception messages to pinpoint the offending value. +- Adds a GDB pretty-printer and a [`cbor_tag_handler_t`](https://json.nlohmann.me/api/basic_json/cbor_tag_handler_t/index.md) `store` option to keep CBOR tags as binary subtypes. +- Supports containers with non-default-constructible types and parsing from `std::byte`. +- Adds [`JSON_NO_IO`](https://json.nlohmann.me/api/macros/json_no_io/index.md) to exclude the I/O headers and the [`JSON_HAS_CPP_*`](https://json.nlohmann.me/api/macros/json_has_cpp_11/index.md) macros to override the detected C++ standard. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.10.0). + +## v3.9.1 (2020-08-06) + +Fixes two regressions from 3.9.0. All changes are backward-compatible. + +- Accepts consecutive [comments](https://json.nlohmann.me/features/comments/index.md) and completes the [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) interface (e.g. `ordered_json::parse`). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.9.1). + +## v3.9.0 (2020-07-27) + +Feature release adding four long-requested features. All changes are backward-compatible. + +- Optional [comment](https://json.nlohmann.me/features/comments/index.md) parsing in [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) via the `ignore_comments` parameter. +- [`ordered_json`](https://json.nlohmann.me/api/ordered_json/index.md) to preserve the [insertion order](https://json.nlohmann.me/features/object_order/index.md) of object keys. +- An option to switch off [implicit conversions](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md). +- The [`NLOHMANN_DEFINE_TYPE_*`](https://json.nlohmann.me/features/arbitrary_types/#simplify-your-life-with-macros) convenience macros, plus high-precision-number support for [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) and CBOR tag handling. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.9.0). + +## v3.8.0 (2020-06-14) + +Feature release. All changes are backward-compatible. + +- Introduces a [binary value](https://json.nlohmann.me/features/binary_values/index.md) type that is read from and written to [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md), [BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md), and [MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md), and can be shared between formats. +- Generalizes the input adapters to read from any `LegacyInputIterator` container (3–10 % faster parsing). +- Fixes [`contains`](https://json.nlohmann.me/api/basic_json/contains/index.md) for JSON pointers and makes the binary [`from_cbor`](https://json.nlohmann.me/api/basic_json/from_cbor/index.md)/[`from_msgpack`](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md)/etc. functions respect `allow_exceptions`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.8.0). + +## v3.7.3 (2019-11-17) + +Fixes a regression from 3.7.2 that could yield quadratic complexity in destructor calls. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.3). + +## v3.7.2 (2019-11-10) + +Fixes a stack overflow for deeply nested input by making the destructor iterative; parsing is now bounded only by available memory. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.2). + +## v3.7.1 (2019-11-06) + +Bug-fix release. All changes are backward-compatible. + +- Fixes a segmentation fault when serializing the `std::int64_t` minimum value and fixes [`contains`](https://json.nlohmann.me/api/basic_json/contains/index.md) for JSON pointers. +- Allows [`items`](https://json.nlohmann.me/api/basic_json/items/index.md) with a custom string type and makes `json_pointer::back` `const`. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.1). + +## v3.7.0 (2019-07-28) + +Convenience features and house-keeping. All changes are backward-compatible. + +- Adds a [`contains`](https://json.nlohmann.me/api/basic_json/contains/index.md) overload that checks a JSON pointer without throwing, a generic `to_string`, and a return value for [`emplace_back`](https://json.nlohmann.me/api/basic_json/emplace_back/index.md). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.7.0). + +## v3.6.1 (2019-03-20) + +Fixes a regression (GCC 7/8 compilation) and a `` build error introduced in 3.6.0. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.6.1). + +## v3.6.0 (2019-03-20) + +Feature release. All changes are backward-compatible. + +- Reworks the [JSON pointer](https://json.nlohmann.me/features/json_pointer/index.md) interface (`operator/`, `push_back`, `parent_pointer`, …). +- Adds a [`contains`](https://json.nlohmann.me/api/basic_json/contains/index.md) function to test for an object key and greatly improves the performance of integer serialization. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.6.0). + +## v3.5.0 (2018-12-22) + +Feature release. All changes are backward-compatible. + +- Adds structured-binding support via the [`items`](https://json.nlohmann.me/api/basic_json/items/index.md) function and reading from `FILE*` in the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function. +- Fixes the `eofbit` handling on input streams and a bug in the BSON SAX parser. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.5.0). + +## v3.4.0 (2018-10-30) + +Feature release. All changes are backward-compatible. + +- Adds [BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md) read/write support. +- Adds configurable Unicode error handlers to [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) (throw, replace with U+FFFD, or ignore) and the [`NLOHMANN_JSON_SERIALIZE_ENUM`](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) macro for [enum conversion](https://json.nlohmann.me/features/enum_conversion/index.md). +- Improves parse-error messages with line/column positions and context. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.4.0). + +## v3.3.0 (2018-10-05) + +Feature release. All changes are backward-compatible. + +- Adds GCC 4.8 support, the [`get_to`](https://json.nlohmann.me/api/basic_json/get_to/index.md) function, and an overhauled and documented [CMake](https://json.nlohmann.me/integration/cmake/index.md) integration. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.3.0). + +## v3.2.0 (2018-08-20) + +Feature release. All changes are backward-compatible. + +- Adds a [SAX interface](https://json.nlohmann.me/features/parsing/sax_interface/index.md) and a non-recursive parser. +- Adds parsing from wide-string types (`std::wstring`, `std::u16string`, `std::u32string`) and `std::string_view` (C++17), and round-tripping of `std::map`/`std::unordered_map` with non-string keys. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.2.0). + +## v3.1.2 (2018-03-14) + +Bug-fix release. All changes are backward-compatible. + +- Fixes a memory leak in the parser callback and adds user-defined string-type support to the parser and serializer. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.1.2). + +## v3.1.1 (2018-02-13) + +Bug-fix release. All changes are backward-compatible. + +- Fixes parsing of indefinite-length CBOR strings, a user-defined conversion to vector types, and overflow detection for UBJSON containers. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.1.1). + +## v3.1.0 (2018-02-01) + +Feature release. All changes are backward-compatible. + +- Adds [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) read/write support and [JSON Merge Patch](https://json.nlohmann.me/features/merge_patch/index.md) via [`merge_patch`](https://json.nlohmann.me/api/basic_json/merge_patch/index.md). +- Switches to the Grisu2 algorithm for short, round-trippable floating-point output, and splits the header into [multiple files](https://json.nlohmann.me/integration/index.md) with a forward-declaration header. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.1.0). + +## v3.0.1 (2017-12-29) + +Fixes small issues in the [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) and [JSON Patch](https://json.nlohmann.me/features/json_patch/index.md) implementations (invalid "copy" targets and non-integer array indices). All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v3.0.1). + +## v3.0.0 (2017-12-17) + +First 3.x release — a major release with breaking changes (see the [migration guide](https://json.nlohmann.me/integration/migration_guide/index.md)). + +- Introduces user-defined [exceptions](https://json.nlohmann.me/home/exceptions/index.md) (`json::exception` and subtypes, each with an identifier). +- Adds a non-throwing [`accept`](https://json.nlohmann.me/api/basic_json/accept/index.md) function and an `allow_exceptions` flag for [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md), and an [`update`](https://json.nlohmann.me/api/basic_json/update/index.md) function to merge objects. +- Adds streaming for CBOR and MessagePack and allows storing NaN/infinity. +- Non-UTF-8 strings now throw on serialization, and the iterator category changed to bidirectional. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v3.0.0). + +## v2.1.1 (2017-02-25) + +Bug-fix release. All changes are backward-compatible. + +- Makes number parsing and serialization locale-independent with correct floating-point round-tripping; released files are now GPG-signed. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.1.1). + +## v2.1.0 (2017-01-28) + +Feature release. All changes are backward-compatible. + +- Adds conversions from and to [arbitrary user-defined types](https://json.nlohmann.me/features/arbitrary_types/index.md) via `to_json`/`from_json`, the [`meta`](https://json.nlohmann.me/api/basic_json/meta/index.md) function, and the option to switch off exceptions ([`JSON_NOEXCEPTION`](https://json.nlohmann.me/api/macros/json_noexception/index.md)). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.1.0). + +## v2.0.10 (2017-01-02) + +Fixes several security-relevant bugs in the CBOR and MessagePack parsers found by OSS-Fuzz. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.10). + +## v2.0.9 (2016-12-16) + +Adds the [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md) and [MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md) binary formats. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.9). + +## v2.0.8 (2016-12-02) + +Adds the [`emplace`](https://json.nlohmann.me/api/basic_json/emplace/index.md) and [`emplace_back`](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) functions and improves parsing and serialization performance. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.8). + +## v2.0.7 (2016-11-02) + +Fixes several parser bugs found through the "Parsing JSON is a Minefield" study (short files, encoding detection, surrogate pairs). All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.7). + +## v2.0.6 (2016-10-15) + +Fixes [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md) for [JSON pointers](https://json.nlohmann.me/features/json_pointer/index.md) so that it creates missing values like the other overloads. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.6). + +## v2.0.5 (2016-09-14) + +Fixes a remaining stream end-of-file detection bug in the parser. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.5). + +## v2.0.4 (2016-09-11) + +Fixes stream end-of-file detection in the parser. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.4). + +## v2.0.3 (2016-08-31) + +Generalizes the parser to accept any contiguous sequence of one-byte elements and deprecates the input-stream constructor in favor of the [`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md) function. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.3). + +## v2.0.2 (2016-07-31) + +Overhauls the parser (now rejecting unescaped control characters), tightens the class invariants, and cleans up the code. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.2). + +## v2.0.1 (2016-06-28) + +Fixes a performance regression in the [`dump`](https://json.nlohmann.me/api/basic_json/dump/index.md) function by adjusting the stream locale once per serialization. All changes are backward-compatible. [Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.1). + +## v2.0.0 (2016-06-24) + +Feature release with a minor (potentially non-backward-compatible) API change from added `noexcept` and `constexpr` specifiers. + +- Adds [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) support in [`at`](https://json.nlohmann.me/api/basic_json/at/index.md) and [`operator[]`](https://json.nlohmann.me/api/basic_json/operator%5B%5D/index.md), plus [`flatten`](https://json.nlohmann.me/api/basic_json/flatten/index.md) and [`unflatten`](https://json.nlohmann.me/api/basic_json/unflatten/index.md). +- Adds [JSON Patch](https://json.nlohmann.me/features/json_patch/index.md) via [`diff`](https://json.nlohmann.me/api/basic_json/diff/index.md) and [`patch`](https://json.nlohmann.me/api/basic_json/patch/index.md), unsigned 64-bit integer support, and locale-independent serialization. + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v2.0.0). + +## v1.1.0 (2016-01-24) + +Bug-fix and feature release. All changes are backward-compatible. + +- Improves floating-point round-tripping, adds a `get_ref` accessor for stored values, and introduces runtime [assertions](https://json.nlohmann.me/features/assertions/index.md). + +[Full release notes](https://github.com/nlohmann/json/releases/tag/v1.1.0). + +## v1.0.0 (2015-12-28) + +First official release. [Full release notes](https://github.com/nlohmann/json/releases/tag/v1.0.0). + +## See also + +- [Migration Guide](https://json.nlohmann.me/integration/migration_guide/index.md) — how to future-proof your code for the next major version and replace deprecated functions. diff --git a/home/sponsors.md b/home/sponsors.md new file mode 100644 index 000000000..7e3ef0284 --- /dev/null +++ b/home/sponsors.md @@ -0,0 +1,19 @@ +# Sponsors + +You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann). + +## Priority Sponsor + +- [Martti Laine](https://github.com/codeclown) +- [Paul Harrington](https://github.com/phrrngtn) + +## Named Sponsors + +- [Michael Hartmann](https://github.com/reFX-Mike) +- [Stefan Hagen](https://github.com/sthagen) +- [Steve Sperandeo](https://github.com/homer6) +- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe) +- [Steve Wagner](https://github.com/ciroque) +- [Lion Yang](https://github.com/LionNatsu) + +Thanks everyone! diff --git a/home/sponsors/index.html b/home/sponsors/index.html index 02a47a318..15e801805 100644 --- a/home/sponsors/index.html +++ b/home/sponsors/index.html @@ -1 +1 @@ - Sponsors - JSON for Modern C++
    \ No newline at end of file + Sponsors - JSON for Modern C++
    \ No newline at end of file diff --git a/home/sponsors/index.md b/home/sponsors/index.md new file mode 100644 index 000000000..7e3ef0284 --- /dev/null +++ b/home/sponsors/index.md @@ -0,0 +1,19 @@ +# Sponsors + +You can sponsor this library at [GitHub Sponsors](https://github.com/sponsors/nlohmann). + +## Priority Sponsor + +- [Martti Laine](https://github.com/codeclown) +- [Paul Harrington](https://github.com/phrrngtn) + +## Named Sponsors + +- [Michael Hartmann](https://github.com/reFX-Mike) +- [Stefan Hagen](https://github.com/sthagen) +- [Steve Sperandeo](https://github.com/homer6) +- [Robert Jefe Lindstädt](https://github.com/eljefedelrodeodeljefe) +- [Steve Wagner](https://github.com/ciroque) +- [Lion Yang](https://github.com/LionNatsu) + +Thanks everyone! diff --git a/index.html b/index.html index c08a88765..4f913a59f 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ - JSON for Modern C++ - JSON for Modern C++

    JSON for Modern C++

    \ No newline at end of file + JSON for Modern C++ - JSON for Modern C++

    JSON for Modern C++

    \ No newline at end of file diff --git a/index.md b/index.md new file mode 100644 index 000000000..33573c27c --- /dev/null +++ b/index.md @@ -0,0 +1 @@ +# JSON for Modern C++ diff --git a/integration.md b/integration.md new file mode 100644 index 000000000..2bbaa8604 --- /dev/null +++ b/integration.md @@ -0,0 +1,18 @@ +# Header only + +[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required +file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add + +```cpp +#include + +// for convenience +using json = nlohmann::json; +``` + +to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and +Clang). + +You can further use file +[`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) +for forward declarations. diff --git a/integration/cmake.md b/integration/cmake.md new file mode 100644 index 000000000..6bdaa4524 --- /dev/null +++ b/integration/cmake.md @@ -0,0 +1,183 @@ +# CMake + +## Integration + +You can use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage +requirements for [`INTERFACE_INCLUDE_DIRECTORIES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html) +to point to the appropriate include directories and [`INTERFACE_COMPILE_FEATURES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_COMPILE_FEATURES.html) +for the necessary C++11 flags. + +### External + +To use this library from a CMake project, you can locate it directly with [`find_package()`](https://cmake.org/cmake/help/latest/command/find_package.html) +and use the namespaced imported target from the generated package configuration: + +!!! example + + ```cmake title="CMakeLists.txt" + cmake_minimum_required(VERSION 3.5) + project(ExampleProject LANGUAGES CXX) + + find_package(nlohmann_json 3.12.0 REQUIRED) + + add_executable(example example.cpp) + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + +The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of +the build tree. + +### Embedded + +To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call +`add_subdirectory()` in your `CMakeLists.txt` file. + +!!! example + + ```cmake title="CMakeLists.txt" + cmake_minimum_required(VERSION 3.5) + project(ExampleProject LANGUAGES CXX) + + # If you only include this third party in PRIVATE source files, you do not need to install it + # when your main project gets installed. + set(JSON_Install OFF CACHE INTERNAL "") + + add_subdirectory(nlohmann_json) + + add_executable(example example.cpp) + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + +!!! note + + Do not use `#!cmake include(nlohmann_json/CMakeLists.txt)`, since that carries with it unintended consequences that + will break the build. It is generally discouraged (although not necessarily well documented as such) to use + `#!cmake include(...)` for pulling in other CMake projects anyways. + + +### Supporting Both + +To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin +to the following. + +!!! example + + ```cmake title="CMakeLists.txt" + project(ExampleProject LANGUAGES CXX) + + option(EXAMPLE_USE_EXTERNAL_JSON "Use an external JSON library" OFF) + + add_subdirectory(thirdparty) + + add_executable(example example.cpp) + + # Note that the namespaced target will always be available regardless of the import method + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + + ```cmake title="thirdparty/CMakeLists.txt" + if(EXAMPLE_USE_EXTERNAL_JSON) + find_package(nlohmann_json 3.12.0 REQUIRED) + else() + set(JSON_BuildTests OFF CACHE INTERNAL "") + add_subdirectory(nlohmann_json) + endif() + ``` + + `thirdparty/nlohmann_json` is then a complete copy of this source tree. + + +### FetchContent + +Since CMake v3.11, [FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can be used to +automatically download a release as a dependency at configure time. + +!!! example + + ```cmake title="CMakeLists.txt" + cmake_minimum_required(VERSION 3.11) + project(ExampleProject LANGUAGES CXX) + + include(FetchContent) + + FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz) + FetchContent_MakeAvailable(json) + + add_executable(example example.cpp) + target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) + ``` + +!!! Note + + It is recommended to use the URL approach described above which is supported as of version 3.10.0. It is also + possible to pass the Git repository like + + ```cmake + FetchContent_Declare(json + GIT_REPOSITORY https://github.com/nlohmann/json + GIT_TAG v3.12.0 + ) + ``` + + However, the repository download size is quite large. + +## CMake Options + +### `JSON_BuildTests` + +Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option. + +### `JSON_CI` + +Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default. + +### `JSON_Diagnostics` + +Enable [extended diagnostic messages](../home/exceptions.md#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](../api/macros/json_diagnostics.md). This option is `OFF` by default. + +### `JSON_Diagnostic_Positions` + +Enable position diagnostics by defining macro [`JSON_DIAGNOSTIC_POSITIONS`](../api/macros/json_diagnostic_positions.md). This option is `OFF` by default. + +### `JSON_DisableEnumSerialization` + +Disable default `enum` serialization by defining the macro +[`JSON_DISABLE_ENUM_SERIALIZATION`](../api/macros/json_disable_enum_serialization.md). This option is `OFF` by default. + +### `JSON_FastTests` + +Skip expensive/slow test suites. This option is `OFF` by default. Depends on `JSON_BuildTests`. + +### `JSON_GlobalUDLs` + +Place user-defined string literals in the global namespace by defining the macro +[`JSON_USE_GLOBAL_UDLS`](../api/macros/json_use_global_udls.md). This option is `OFF` by default. + +### `JSON_ImplicitConversions` + +Enable implicit conversions by defining macro [`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md). This option is `ON` by default. + +### `JSON_Install` + +Install CMake targets during install step. This option is `ON` by default if the library's CMake project is the top project. + +### `JSON_LegacyDiscardedValueComparison` + +Enable the (incorrect) legacy comparison behavior of discarded JSON values by defining macro [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md). This option is `OFF` by default. + +### `JSON_MultipleHeaders` + +Use the non-amalgamated version of the library. This option is `ON` by default. + +### `JSON_SystemInclude` + +Treat the library headers like system headers (i.e., adding `SYSTEM` to the [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html) call) to check for this library by tools like Clang-Tidy. This option is `OFF` by default. + +### `JSON_Valgrind` + +Execute the test suite with [Valgrind](https://valgrind.org). This option is `OFF` by default. Depends on `JSON_BuildTests`. + +### `NLOHMANN_JSON_BUILD_MODULES` + +Build the experimental [C++ module](../features/modules.md) `nlohmann.json` (requires CMake 3.28 or later and C++20). +This option is `OFF` by default. diff --git a/integration/cmake/index.html b/integration/cmake/index.html index 9b9613923..876ed9e01 100644 --- a/integration/cmake/index.html +++ b/integration/cmake/index.html @@ -46,4 +46,4 @@ GIT_REPOSITORY https://github.com/nlohmann/json GIT_TAG v3.12.0 ) -

    However, the repository https://github.com/nlohmann/json download size is quite large.

    CMake Options

    JSON_BuildTests

    Build the unit tests when BUILD_TESTING is enabled. This option is ON by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.

    JSON_CI

    Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is OFF by default.

    JSON_Diagnostics

    Enable extended diagnostic messages by defining macro JSON_DIAGNOSTICS. This option is OFF by default.

    JSON_Diagnostic_Positions

    Enable position diagnostics by defining macro JSON_DIAGNOSTIC_POSITIONS. This option is OFF by default.

    JSON_DisableEnumSerialization

    Disable default enum serialization by defining the macro JSON_DISABLE_ENUM_SERIALIZATION. This option is OFF by default.

    JSON_FastTests

    Skip expensive/slow test suites. This option is OFF by default. Depends on JSON_BuildTests.

    JSON_GlobalUDLs

    Place user-defined string literals in the global namespace by defining the macro JSON_USE_GLOBAL_UDLS. This option is OFF by default.

    JSON_ImplicitConversions

    Enable implicit conversions by defining macro JSON_USE_IMPLICIT_CONVERSIONS. This option is ON by default.

    JSON_Install

    Install CMake targets during install step. This option is ON by default if the library's CMake project is the top project.

    JSON_LegacyDiscardedValueComparison

    Enable the (incorrect) legacy comparison behavior of discarded JSON values by defining macro JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON. This option is OFF by default.

    JSON_MultipleHeaders

    Use the non-amalgamated version of the library. This option is ON by default.

    JSON_SystemInclude

    Treat the library headers like system headers (i.e., adding SYSTEM to the target_include_directories call) to check for this library by tools like Clang-Tidy. This option is OFF by default.

    JSON_Valgrind

    Execute the test suite with Valgrind. This option is OFF by default. Depends on JSON_BuildTests.

    NLOHMANN_JSON_BUILD_MODULES

    Build the experimental C++ module nlohmann.json (requires CMake 3.28 or later and C++20). This option is OFF by default.

    \ No newline at end of file +

    However, the repository https://github.com/nlohmann/json download size is quite large.

    CMake Options

    JSON_BuildTests

    Build the unit tests when BUILD_TESTING is enabled. This option is ON by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.

    JSON_CI

    Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is OFF by default.

    JSON_Diagnostics

    Enable extended diagnostic messages by defining macro JSON_DIAGNOSTICS. This option is OFF by default.

    JSON_Diagnostic_Positions

    Enable position diagnostics by defining macro JSON_DIAGNOSTIC_POSITIONS. This option is OFF by default.

    JSON_DisableEnumSerialization

    Disable default enum serialization by defining the macro JSON_DISABLE_ENUM_SERIALIZATION. This option is OFF by default.

    JSON_FastTests

    Skip expensive/slow test suites. This option is OFF by default. Depends on JSON_BuildTests.

    JSON_GlobalUDLs

    Place user-defined string literals in the global namespace by defining the macro JSON_USE_GLOBAL_UDLS. This option is OFF by default.

    JSON_ImplicitConversions

    Enable implicit conversions by defining macro JSON_USE_IMPLICIT_CONVERSIONS. This option is ON by default.

    JSON_Install

    Install CMake targets during install step. This option is ON by default if the library's CMake project is the top project.

    JSON_LegacyDiscardedValueComparison

    Enable the (incorrect) legacy comparison behavior of discarded JSON values by defining macro JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON. This option is OFF by default.

    JSON_MultipleHeaders

    Use the non-amalgamated version of the library. This option is ON by default.

    JSON_SystemInclude

    Treat the library headers like system headers (i.e., adding SYSTEM to the target_include_directories call) to check for this library by tools like Clang-Tidy. This option is OFF by default.

    JSON_Valgrind

    Execute the test suite with Valgrind. This option is OFF by default. Depends on JSON_BuildTests.

    NLOHMANN_JSON_BUILD_MODULES

    Build the experimental C++ module nlohmann.json (requires CMake 3.28 or later and C++20). This option is OFF by default.

    \ No newline at end of file diff --git a/integration/cmake/index.md b/integration/cmake/index.md new file mode 100644 index 000000000..c95e3b2f5 --- /dev/null +++ b/integration/cmake/index.md @@ -0,0 +1,177 @@ +# CMake + +## Integration + +You can use the `nlohmann_json::nlohmann_json` interface target in CMake. This target populates the appropriate usage requirements for [`INTERFACE_INCLUDE_DIRECTORIES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html) to point to the appropriate include directories and [`INTERFACE_COMPILE_FEATURES`](https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_COMPILE_FEATURES.html) for the necessary C++11 flags. + +### External + +To use this library from a CMake project, you can locate it directly with [`find_package()`](https://cmake.org/cmake/help/latest/command/find_package.html) and use the namespaced imported target from the generated package configuration: + +Example + +CMakeLists.txt + +``` +cmake_minimum_required(VERSION 3.5) +project(ExampleProject LANGUAGES CXX) + +find_package(nlohmann_json 3.12.0 REQUIRED) + +add_executable(example example.cpp) +target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) +``` + +The package configuration file, `nlohmann_jsonConfig.cmake`, can be used either from an install tree or directly out of the build tree. + +### Embedded + +To embed the library directly into an existing CMake project, place the entire source tree in a subdirectory and call `add_subdirectory()` in your `CMakeLists.txt` file. + +Example + +CMakeLists.txt + +``` +cmake_minimum_required(VERSION 3.5) +project(ExampleProject LANGUAGES CXX) + +# If you only include this third party in PRIVATE source files, you do not need to install it +# when your main project gets installed. +set(JSON_Install OFF CACHE INTERNAL "") + +add_subdirectory(nlohmann_json) + +add_executable(example example.cpp) +target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) +``` + +Note + +Do not use `include(nlohmann_json/CMakeLists.txt)`, since that carries with it unintended consequences that will break the build. It is generally discouraged (although not necessarily well documented as such) to use `include(...)` for pulling in other CMake projects anyways. + +### Supporting Both + +To allow your project to support either an externally supplied or an embedded JSON library, you can use a pattern akin to the following. + +Example + +CMakeLists.txt + +``` +project(ExampleProject LANGUAGES CXX) + +option(EXAMPLE_USE_EXTERNAL_JSON "Use an external JSON library" OFF) + +add_subdirectory(thirdparty) + +add_executable(example example.cpp) + +# Note that the namespaced target will always be available regardless of the import method +target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) +``` + +thirdparty/CMakeLists.txt + +``` +if(EXAMPLE_USE_EXTERNAL_JSON) + find_package(nlohmann_json 3.12.0 REQUIRED) +else() + set(JSON_BuildTests OFF CACHE INTERNAL "") + add_subdirectory(nlohmann_json) +endif() +``` + +`thirdparty/nlohmann_json` is then a complete copy of this source tree. + +### FetchContent + +Since CMake v3.11, [FetchContent](https://cmake.org/cmake/help/v3.11/module/FetchContent.html) can be used to automatically download a release as a dependency at configure time. + +Example + +CMakeLists.txt + +``` +cmake_minimum_required(VERSION 3.11) +project(ExampleProject LANGUAGES CXX) + +include(FetchContent) + +FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz) +FetchContent_MakeAvailable(json) + +add_executable(example example.cpp) +target_link_libraries(example PRIVATE nlohmann_json::nlohmann_json) +``` + +Note + +It is recommended to use the URL approach described above which is supported as of version 3.10.0. It is also possible to pass the Git repository like + +``` +FetchContent_Declare(json + GIT_REPOSITORY https://github.com/nlohmann/json + GIT_TAG v3.12.0 +) +``` + +However, the repository download size is quite large. + +## CMake Options + +### `JSON_BuildTests` + +Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option. + +### `JSON_CI` + +Enable CI build targets. The exact targets are used during the several CI steps and are subject to change without notice. This option is `OFF` by default. + +### `JSON_Diagnostics` + +Enable [extended diagnostic messages](https://json.nlohmann.me/home/exceptions/#extended-diagnostic-messages) by defining macro [`JSON_DIAGNOSTICS`](https://json.nlohmann.me/api/macros/json_diagnostics/index.md). This option is `OFF` by default. + +### `JSON_Diagnostic_Positions` + +Enable position diagnostics by defining macro [`JSON_DIAGNOSTIC_POSITIONS`](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md). This option is `OFF` by default. + +### `JSON_DisableEnumSerialization` + +Disable default `enum` serialization by defining the macro [`JSON_DISABLE_ENUM_SERIALIZATION`](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md). This option is `OFF` by default. + +### `JSON_FastTests` + +Skip expensive/slow test suites. This option is `OFF` by default. Depends on `JSON_BuildTests`. + +### `JSON_GlobalUDLs` + +Place user-defined string literals in the global namespace by defining the macro [`JSON_USE_GLOBAL_UDLS`](https://json.nlohmann.me/api/macros/json_use_global_udls/index.md). This option is `OFF` by default. + +### `JSON_ImplicitConversions` + +Enable implicit conversions by defining macro [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md). This option is `ON` by default. + +### `JSON_Install` + +Install CMake targets during install step. This option is `ON` by default if the library's CMake project is the top project. + +### `JSON_LegacyDiscardedValueComparison` + +Enable the (incorrect) legacy comparison behavior of discarded JSON values by defining macro [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/index.md). This option is `OFF` by default. + +### `JSON_MultipleHeaders` + +Use the non-amalgamated version of the library. This option is `ON` by default. + +### `JSON_SystemInclude` + +Treat the library headers like system headers (i.e., adding `SYSTEM` to the [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html) call) to check for this library by tools like Clang-Tidy. This option is `OFF` by default. + +### `JSON_Valgrind` + +Execute the test suite with [Valgrind](https://valgrind.org). This option is `OFF` by default. Depends on `JSON_BuildTests`. + +### `NLOHMANN_JSON_BUILD_MODULES` + +Build the experimental [C++ module](https://json.nlohmann.me/features/modules/index.md) `nlohmann.json` (requires CMake 3.28 or later and C++20). This option is `OFF` by default. diff --git a/integration/index.html b/integration/index.html index 6648df48b..7bec7b7d8 100644 --- a/integration/index.html +++ b/integration/index.html @@ -2,4 +2,4 @@ // for convenience using json = nlohmann::json; -

    to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., -std=c++11 for GCC and Clang).

    You can further use file single_include/nlohmann/json_fwd.hpp for forward declarations.

    \ No newline at end of file +

    to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., -std=c++11 for GCC and Clang).

    You can further use file single_include/nlohmann/json_fwd.hpp for forward declarations.

    \ No newline at end of file diff --git a/integration/index.md b/integration/index.md new file mode 100644 index 000000000..c476e5520 --- /dev/null +++ b/integration/index.md @@ -0,0 +1,14 @@ +# Header only + +[`json.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json.hpp) is the single required file in `single_include/nlohmann` or [released here](https://github.com/nlohmann/json/releases). You need to add + +``` +#include + +// for convenience +using json = nlohmann::json; +``` + +to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang). + +You can further use file [`single_include/nlohmann/json_fwd.hpp`](https://github.com/nlohmann/json/blob/develop/single_include/nlohmann/json_fwd.hpp) for forward declarations. diff --git a/integration/migration_guide.md b/integration/migration_guide.md new file mode 100644 index 000000000..cb1c62d7b --- /dev/null +++ b/integration/migration_guide.md @@ -0,0 +1,260 @@ +# Migration Guide + +This page collects some guidelines on how to future-proof your code for future versions of this library. + +## Replace deprecated functions + +The following functions have been deprecated and will be removed in the next major version (i.e., 4.0.0). All +deprecations are annotated with +[`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which +function to use instead. + +#### Parsing + +- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use + [`friend std::istream& operator>>(std::istream&, basic_json&)`](../api/operator_gtgt.md) instead. + + === "Deprecated" + + ```cpp + nlohmann::json j; + std::stringstream ss("[1,2,3]"); + j << ss; + ``` + + === "Future-proof" + + ```cpp + nlohmann::json j; + std::stringstream ss("[1,2,3]"); + ss >> j; + ``` + +- Passing iterator pairs or pointer/length pairs to parsing functions ([`parse`](../api/basic_json/parse.md), + [`accept`](../api/basic_json/accept.md), [`sax_parse`](../api/basic_json/sax_parse.md), + [`from_cbor`](../api/basic_json/from_cbor.md), [`from_msgpack`](../api/basic_json/from_msgpack.md), + [`from_ubjson`](../api/basic_json/from_ubjson.md), and [`from_bson`](../api/basic_json/from_bson.md) via initializer + lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of + `from_cbor({ptr, len})`. + + === "Deprecated" + + ```cpp + const char* s = "[1,2,3]"; + bool ok = nlohmann::json::accept({s, s + std::strlen(s)}); + ``` + + === "Future-proof" + + ```cpp + const char* s = "[1,2,3]"; + bool ok = nlohmann::json::accept(s, s + std::strlen(s)); + ``` + +#### JSON Pointers + +- Comparing JSON Pointers with strings via [`operator==`](../api/json_pointer/operator_eq.md) and + [`operator!=`](../api/json_pointer/operator_ne.md) is deprecated since 3.11.2. To compare a + [`json_pointer`](../api/json_pointer/index.md) `p` with a string `s`, convert `s` to a `json_pointer` first and use + [`json_pointer::operator==`](../api/json_pointer/operator_eq.md) or + [`json_pointer::operator!=`](../api/json_pointer/operator_ne.md). + + === "Deprecated" + + ```cpp + nlohmann::json::json_pointer lhs("/foo/bar/1"); + assert(lhs == "/foo/bar/1"); + ``` + + === "Future-proof" + + ```cpp + nlohmann::json::json_pointer lhs("/foo/bar/1"); + assert(lhs == nlohmann::json::json_pointer("/foo/bar/1")); + ``` + +- The implicit conversion from JSON Pointers to string + ([`json_pointer::operator string_t`](../api/json_pointer/operator_string_t.md)) is deprecated since 3.11.0. Use + [`json_pointer::to_string`](../api/json_pointer/to_string.md) instead. + + === "Deprecated" + + ```cpp + nlohmann::json::json_pointer ptr("/foo/bar/1"); + std::string s = ptr; + ``` + + === "Future-proof" + + ```cpp + nlohmann::json::json_pointer ptr("/foo/bar/1"); + std::string s = ptr.to_string(); + ``` + +- Passing a `basic_json` specialization as template parameter `RefStringType` to + [`json_pointer`](../api/json_pointer/index.md) is deprecated since 3.11.0. The string type can now be directly + provided. + + === "Deprecated" + + ```cpp + using my_json = nlohmann::basic_json; + nlohmann::json_pointer ptr("/foo/bar/1"); + ``` + + === "Future-proof" + + ```cpp + nlohmann::json_pointer ptr("/foo/bar/1"); + ``` + + Thereby, `nlohmann::my_json::json_pointer` is an alias for `nlohmann::json_pointer` and is always an + alias to the `json_pointer` with the appropriate string type for all specializations of `basic_json`. + +#### Miscellaneous functions + +- The function `iterator_wrapper` is deprecated since 3.1.0. Please use the member function + [`items`](../api/basic_json/items.md) instead. + + === "Deprecated" + + ```cpp + for (auto &x : nlohmann::json::iterator_wrapper(j)) + { + std::cout << x.key() << ":" << x.value() << std::endl; + } + ``` + + === "Future-proof" + + ```cpp + for (auto &x : j.items()) + { + std::cout << x.key() << ":" << x.value() << std::endl; + } + ``` + +- Function `friend std::ostream& operator>>(const basic_json&, std::ostream&)` is deprecated since 3.0.0. Please use + [`friend operator<<(std::ostream&, const basic_json&)`](../api/operator_ltlt.md) instead. + + === "Deprecated" + + ```cpp + j >> std::cout; + ``` + + === "Future-proof" + + ```cpp + std::cout << j; + ``` + +- The legacy comparison behavior for discarded values is deprecated since 3.11.0. It is already disabled by default and + can still be enabled by defining + [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](../api/macros/json_use_legacy_discarded_value_comparison.md) to `1`. + + === "Deprecated" + + ```cpp + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 + #include + ``` + + === "Future-proof" + + ```cpp + #include + ``` + +## Replace implicit conversions + +Implicit conversions via [`operator ValueType`](../api/basic_json/operator_ValueType.md) will be switched off by default +in the next major release of the library. + +You can prepare existing code by already defining +[`JSON_USE_IMPLICIT_CONVERSIONS`](../api/macros/json_use_implicit_conversions.md) to `0` and replace any implicit +conversions with calls to [`get`](../api/basic_json/get.md), [`get_to`](../api/basic_json/get_to.md), +[`get_ref`](../api/basic_json/get_ref.md), or [`get_ptr`](../api/basic_json/get_ptr.md). + +=== "Deprecated" + + ```cpp + nlohmann::json j = "Hello, world!"; + std::string s = j; + ``` + +=== "Future-proof" + + ```cpp + nlohmann::json j = "Hello, world!"; + auto s = j.get(); + ``` + +=== "Future-proof (alternative)" + + ```cpp + nlohmann::json j = "Hello, world!"; + std::string s; + j.get_to(s); + ``` + +## Import namespace `literals` for UDLs + +The user-defined string literals [`operator""_json`](../api/operator_literal_json.md) and +[`operator""_json_pointer`](../api/operator_literal_json_pointer.md) will be removed from the global namespace in the +next major release of the library. + +=== "Deprecated" + + ```cpp + nlohmann::json j = "[1,2,3]"_json; + ``` + +=== "Future-proof" + + ```cpp + using namespace nlohmann::literals; + nlohmann::json j = "[1,2,3]"_json; + ``` + +To prepare existing code, define [`JSON_USE_GLOBAL_UDLS`](../api/macros/json_use_global_udls.md) to `0` and bring the +string literals into scope where needed. + +## Do not hard-code the complete library namespace + +The [`nlohmann` namespace](../features/namespace.md) contains a sub-namespace to avoid problems when different +versions or configurations of the library are used in the same project. Always use `nlohmann` as namespace or, when the +exact version and configuration is relevant, use macro +[`NLOHMANN_JSON_NAMESPACE`](../api/macros/nlohmann_json_namespace.md) to denote the namespace. + +=== "Dangerous" + + ```cpp + void to_json(nlohmann::json_abi_v3_11_2::json& j, const person& p) + { + j["age"] = p.age; + } + ``` + +=== "Future-proof" + + ```cpp + void to_json(nlohmann::json& j, const person& p) + { + j["age"] = p.age; + } + ``` + +=== "Future-proof (alternative)" + + ```cpp + void to_json(NLOHMANN_JSON_NAMESPACE::json& j, const person& p) + { + j["age"] = p.age; + } + ``` + +## Do not use the `details` namespace + +The `details` namespace is not part of the public API of the library and can change in any version without an +announcement. Do not rely on any function or type in the `details` namespace. diff --git a/integration/migration_guide/index.html b/integration/migration_guide/index.html index 3c919e582..476c74057 100644 --- a/integration/migration_guide/index.html +++ b/integration/migration_guide/index.html @@ -54,4 +54,4 @@ { j["age"] = p.age; } -

    Do not use the details namespace

    The details namespace is not part of the public API of the library and can change in any version without an announcement. Do not rely on any function or type in the details namespace.

    \ No newline at end of file +

    Do not use the details namespace

    The details namespace is not part of the public API of the library and can change in any version without an announcement. Do not rely on any function or type in the details namespace.

    \ No newline at end of file diff --git a/integration/migration_guide/index.md b/integration/migration_guide/index.md new file mode 100644 index 000000000..9a76085e1 --- /dev/null +++ b/integration/migration_guide/index.md @@ -0,0 +1,179 @@ +# Migration Guide + +This page collects some guidelines on how to future-proof your code for future versions of this library. + +## Replace deprecated functions + +The following functions have been deprecated and will be removed in the next major version (i.e., 4.0.0). All deprecations are annotated with [`HEDLEY_DEPRECATED_FOR`](https://nemequ.github.io/hedley/api-reference.html#HEDLEY_DEPRECATED_FOR) to report which function to use instead. + +#### Parsing + +- Function `friend std::istream& operator<<(basic_json&, std::istream&)` is deprecated since 3.0.0. Please use [`friend std::istream& operator>>(std::istream&, basic_json&)`](https://json.nlohmann.me/api/operator_gtgt/index.md) instead. + + ``` + nlohmann::json j; + std::stringstream ss("[1,2,3]"); + j << ss; + ``` + + ``` + nlohmann::json j; + std::stringstream ss("[1,2,3]"); + ss >> j; + ``` + +- Passing iterator pairs or pointer/length pairs to parsing functions ([`parse`](https://json.nlohmann.me/api/basic_json/parse/index.md), [`accept`](https://json.nlohmann.me/api/basic_json/accept/index.md), [`sax_parse`](https://json.nlohmann.me/api/basic_json/sax_parse/index.md), [`from_cbor`](https://json.nlohmann.me/api/basic_json/from_cbor/index.md), [`from_msgpack`](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md), [`from_ubjson`](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md), and [`from_bson`](https://json.nlohmann.me/api/basic_json/from_bson/index.md) via initializer lists is deprecated since 3.8.0. Instead, pass two iterators; for instance, call `from_cbor(ptr, ptr+len)` instead of `from_cbor({ptr, len})`. + + ``` + const char* s = "[1,2,3]"; + bool ok = nlohmann::json::accept({s, s + std::strlen(s)}); + ``` + + ``` + const char* s = "[1,2,3]"; + bool ok = nlohmann::json::accept(s, s + std::strlen(s)); + ``` + +#### JSON Pointers + +- Comparing JSON Pointers with strings via [`operator==`](https://json.nlohmann.me/api/json_pointer/operator_eq/index.md) and [`operator!=`](https://json.nlohmann.me/api/json_pointer/operator_ne/index.md) is deprecated since 3.11.2. To compare a [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) `p` with a string `s`, convert `s` to a `json_pointer` first and use [`json_pointer::operator==`](https://json.nlohmann.me/api/json_pointer/operator_eq/index.md) or [`json_pointer::operator!=`](https://json.nlohmann.me/api/json_pointer/operator_ne/index.md). + + ``` + nlohmann::json::json_pointer lhs("/foo/bar/1"); + assert(lhs == "/foo/bar/1"); + ``` + + ``` + nlohmann::json::json_pointer lhs("/foo/bar/1"); + assert(lhs == nlohmann::json::json_pointer("/foo/bar/1")); + ``` + +- The implicit conversion from JSON Pointers to string ([`json_pointer::operator string_t`](https://json.nlohmann.me/api/json_pointer/operator_string_t/index.md)) is deprecated since 3.11.0. Use [`json_pointer::to_string`](https://json.nlohmann.me/api/json_pointer/to_string/index.md) instead. + + ``` + nlohmann::json::json_pointer ptr("/foo/bar/1"); + std::string s = ptr; + ``` + + ``` + nlohmann::json::json_pointer ptr("/foo/bar/1"); + std::string s = ptr.to_string(); + ``` + +- Passing a `basic_json` specialization as template parameter `RefStringType` to [`json_pointer`](https://json.nlohmann.me/api/json_pointer/index.md) is deprecated since 3.11.0. The string type can now be directly provided. + + ``` + using my_json = nlohmann::basic_json; + nlohmann::json_pointer ptr("/foo/bar/1"); + ``` + + ``` + nlohmann::json_pointer ptr("/foo/bar/1"); + ``` + + Thereby, `nlohmann::my_json::json_pointer` is an alias for `nlohmann::json_pointer` and is always an alias to the `json_pointer` with the appropriate string type for all specializations of `basic_json`. + +#### Miscellaneous functions + +- The function `iterator_wrapper` is deprecated since 3.1.0. Please use the member function [`items`](https://json.nlohmann.me/api/basic_json/items/index.md) instead. + + ``` + for (auto &x : nlohmann::json::iterator_wrapper(j)) + { + std::cout << x.key() << ":" << x.value() << std::endl; + } + ``` + + ``` + for (auto &x : j.items()) + { + std::cout << x.key() << ":" << x.value() << std::endl; + } + ``` + +- Function `friend std::ostream& operator>>(const basic_json&, std::ostream&)` is deprecated since 3.0.0. Please use [`friend operator<<(std::ostream&, const basic_json&)`](https://json.nlohmann.me/api/operator_ltlt/index.md) instead. + + ``` + j >> std::cout; + ``` + + ``` + std::cout << j; + ``` + +- The legacy comparison behavior for discarded values is deprecated since 3.11.0. It is already disabled by default and can still be enabled by defining [`JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON`](https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/index.md) to `1`. + + ``` + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 + #include + ``` + + ``` + #include + ``` + +## Replace implicit conversions + +Implicit conversions via [`operator ValueType`](https://json.nlohmann.me/api/basic_json/operator_ValueType/index.md) will be switched off by default in the next major release of the library. + +You can prepare existing code by already defining [`JSON_USE_IMPLICIT_CONVERSIONS`](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) to `0` and replace any implicit conversions with calls to [`get`](https://json.nlohmann.me/api/basic_json/get/index.md), [`get_to`](https://json.nlohmann.me/api/basic_json/get_to/index.md), [`get_ref`](https://json.nlohmann.me/api/basic_json/get_ref/index.md), or [`get_ptr`](https://json.nlohmann.me/api/basic_json/get_ptr/index.md). + +``` +nlohmann::json j = "Hello, world!"; +std::string s = j; +``` + +``` +nlohmann::json j = "Hello, world!"; +auto s = j.get(); +``` + +``` +nlohmann::json j = "Hello, world!"; +std::string s; +j.get_to(s); +``` + +## Import namespace `literals` for UDLs + +The user-defined string literals [`operator""_json`](https://json.nlohmann.me/api/operator_literal_json/index.md) and [`operator""_json_pointer`](https://json.nlohmann.me/api/operator_literal_json_pointer/index.md) will be removed from the global namespace in the next major release of the library. + +``` +nlohmann::json j = "[1,2,3]"_json; +``` + +``` +using namespace nlohmann::literals; +nlohmann::json j = "[1,2,3]"_json; +``` + +To prepare existing code, define [`JSON_USE_GLOBAL_UDLS`](https://json.nlohmann.me/api/macros/json_use_global_udls/index.md) to `0` and bring the string literals into scope where needed. + +## Do not hard-code the complete library namespace + +The [`nlohmann` namespace](https://json.nlohmann.me/features/namespace/index.md) contains a sub-namespace to avoid problems when different versions or configurations of the library are used in the same project. Always use `nlohmann` as namespace or, when the exact version and configuration is relevant, use macro [`NLOHMANN_JSON_NAMESPACE`](https://json.nlohmann.me/api/macros/nlohmann_json_namespace/index.md) to denote the namespace. + +``` +void to_json(nlohmann::json_abi_v3_11_2::json& j, const person& p) +{ + j["age"] = p.age; +} +``` + +``` +void to_json(nlohmann::json& j, const person& p) +{ + j["age"] = p.age; +} +``` + +``` +void to_json(NLOHMANN_JSON_NAMESPACE::json& j, const person& p) +{ + j["age"] = p.age; +} +``` + +## Do not use the `details` namespace + +The `details` namespace is not part of the public API of the library and can change in any version without an announcement. Do not rely on any function or type in the `details` namespace. diff --git a/integration/package_managers.md b/integration/package_managers.md new file mode 100644 index 000000000..79f872f85 --- /dev/null +++ b/integration/package_managers.md @@ -0,0 +1,937 @@ +# Package Managers + +

    +![Homebrew](../images/package_managers/homebrew.svg){: style="height:1em"} [**Homebrew**](#homebrew) `nlohmann-json`   +![Meson](../images/package_managers/meson.svg){: style="height:1em"} [**Meson**](#meson) `nlohmann_json`   +![Bazel](../images/package_managers/bazel.svg){: style="height:1em"} [**Bazel**](#bazel) `nlohmann_json`
    +![Conan](../images/package_managers/conan.svg){: style="height:1em"} [**Conan**](#conan) `nlohmann_json`   +![Spack](../images/package_managers/spack.svg){: style="height:1em"} [**Spack**](#spack) `nlohmann-json`   +[**Hunter**](#hunter) `nlohmann_json`
    +![vcpkg](../images/package_managers/vcpkg.png){: style="height:1em"} [**vcpkg**](#vcpkg) `nlohmann-json`   +[**cget**](#cget) `nlohmann/json`   +![Swift Package Manager](../images/package_managers/swift.svg){: style="height:1em"} [**Swift Package Manager**](#swift-package-manager) `nlohmann/json`
    +![Nuget](../images/package_managers/nuget.svg){: style="height:1em"} [**NuGet**](#nuget) `nlohmann.json`   +![Conda](../images/package_managers/conda.svg){: style="height:1em"} [**Conda**](#conda) `nlohmann_json`   +![MacPorts](../images/package_managers/macports.svg){: style="height:1em"} [**MacPorts**](#macports) `nlohmann-json`
    +![cpm.cmake](../images/package_managers/CPM.png){: style="height:1em"} [**CPM.cmake**](#cpmcmake) `gh:nlohmann/json`   +![xmake](../images/package_managers/xmake.svg){: style="height:1em"} [**xmake**](#xmake) `nlohmann_json` +

    + +## Running example + +Throughout this page, we will describe how to compile the example file `example.cpp` below. + +```cpp +--8<-- "integration/example.cpp" +``` + +When executed, this program should create output similar to + +```json +--8<-- "examples/meta.output" +``` + +## Homebrew + +!!! abstract "Summary" + + formula: [**`nlohmann-json`**](https://formulae.brew.sh/formula/nlohmann-json) + + - [![Homebrew package](https://repology.org/badge/version-for-repo/homebrew/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + - :octicons-tag-24: Available versions: current version and development version (with `--HEAD` parameter) + - :octicons-rocket-24: The formula is updated with every release. + - :octicons-person-24: Maintainer: Niels Lohmann + - :octicons-file-24: File issues at the [Homebrew issue tracker](https://github.com/Homebrew/homebrew-core/issues) + - :octicons-question-24: [Homebrew website](https://brew.sh) + +If you are using [Homebrew](http://brew.sh), you can install the library with + +```sh +brew install nlohmann-json +``` + +The header can be used directly in your code or via CMake. + +??? example "Example: Raw compilation" + + 1. Create the following file: + + ```cpp title="example.cpp" + --8<-- "integration/homebrew/example.cpp" + ``` + + 2. Install the package: + + ```sh + brew install nlohmann-json + ``` + + 3. Compile the code and pass the Homebrew prefix to the include path such that the library can be found: + + ```sh + c++ example.cpp -I$(brew --prefix nlohmann-json)/include -std=c++11 -o example + ``` + +??? example "Example: CMake" + + 1. Create the following files: + + ```cpp title="example.cpp" + --8<-- "integration/homebrew/example.cpp" + ``` + + ```cmake title="CMakeLists.txt" + --8<-- "integration/homebrew/CMakeLists.txt" + ``` + + 2. Install the package: + + ```sh + brew install nlohmann-json + ``` + + 3. Compile the code and pass the Homebrew prefix to CMake to find installed packages via `#!cmake find_package`: + + ```sh + CMAKE_PREFIX_PATH=$(brew --prefix) cmake -S . -B build + cmake --build build + ``` + +## Meson + +!!! abstract "Summary" + + wrap: **`nlohmann_json`** + + - :octicons-tag-24: Available versions: current version and select older versions (see + [WrapDB](https://mesonbuild.com/Wrapdb-projects.html)) + - :octicons-rocket-24: The package is updated automatically from file + [`meson.build`](https://github.com/nlohmann/json/blob/develop/meson.build). + - :octicons-file-24: File issues at the [library issue tracker](https://github.com/nlohmann/json/issues) + - :octicons-question-24: [Meson website](https://mesonbuild.com/index.html) + +If you are using the [Meson Build System](http://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the +`include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, +you can get a wrap file by downloading it from [Meson WrapDB](https://mesonbuild.com/Wrapdb-projects.html), or use + +```shell +meson wrap install nlohmann_json +``` + +Please see the Meson project for any issues regarding the packaging. + +The provided `meson.build` can also be used as an alternative to CMake for installing `nlohmann_json` system-wide in +which case a pkg-config file is installed. To use it, have your build system require the `nlohmann_json` +pkg-config dependency. In Meson, it is preferred to use the +[`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than +using the subproject directly. + +??? example "Example: Wrap" + + 1. Create the following files: + + ```ini title="meson.build" + --8<-- "integration/meson/meson.build" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/meson/example.cpp" + ``` + + 2. Use the Meson WrapDB to fetch the nlohmann/json wrap: + + ```shell + mkdir subprojects + meson wrap install nlohmann_json + ``` + + 3. Build: + + ```shell + meson setup build + meson compile -C build + ``` + +## Bazel + +!!! abstract "Summary" + + use `bazel_dep`, `git_override`, or `local_path_override` + + - :octicons-tag-24: Any version, that is available via [Bazel Central Registry](https://registry.bazel.build/modules/nlohmann_json) + - :octicons-file-24: File issues at the [library issue tracker](https://github.com/nlohmann/json/issues) + - :octicons-question-24: [Bazel website](https://bazel.build) + +This repository provides a [Bazel](https://bazel.build/) `MODULE.bazel` and a corresponding `BUILD.bazel` file. Therefore, this +repository can be referenced within a `MODULE.bazel` by rules such as `archive_override`, `git_override`, or `local_path_override`. To use the library, you need to depend on the target `@nlohmann_json//:json` (i.e., via `deps` attribute). + +??? example + + 1. Create the following files: + + ```ini title="BUILD" + --8<-- "integration/bazel/BUILD" + ``` + + ```ini title="WORKSPACE" + --8<-- "integration/bazel/MODULE.bazel" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/bazel/example.cpp" + ``` + + 2. Build and run: + + ```shell + bazel build //:main + bazel run //:main + ``` + +## Conan + +!!! abstract "Summary" + + recipe: [**`nlohmann_json`**](https://conan.io/center/recipes/nlohmann_json) + + - [![ConanCenter package](https://repology.org/badge/version-for-repo/conancenter/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + - :octicons-tag-24: Available versions: current version and older versions (see + [Conan Center](https://conan.io/center/recipes/nlohmann_json)) + - :octicons-rocket-24: The package is updated automatically via + [this recipe](https://github.com/conan-io/conan-center-index/tree/master/recipes/nlohmann_json). + - :octicons-file-24: File issues at the [Conan Center issue tracker](https://github.com/conan-io/conan-center-index/issues) + - :octicons-question-24: [Conan website](https://conan.io) + +If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `nlohmann_json/x.y.z` to your `conanfile`'s +requires, where `x.y.z` is the release version you want to use. + +??? example + + 1. Create the following files: + + ```ini title="Conanfile.txt" + --8<-- "integration/conan/Conanfile.txt" + ``` + + ```cmake title="CMakeLists.txt" + --8<-- "integration/conan/CMakeLists.txt" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/conan/example.cpp" + ``` + + 2. Call Conan: + + ```sh + conan install . --output-folder=build --build=missing + ``` + + 3. Build: + + ```sh + cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release + cmake --build build + ``` + +## Spack + +!!! abstract "Summary" + + package: [**`nlohmann-json`**](https://packages.spack.io/package.html?name=nlohmann-json) + + - [![Spack package](https://repology.org/badge/version-for-repo/spack/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + - :octicons-tag-24: Available versions: current version and older versions (see + [Spack package](https://packages.spack.io/package.html?name=nlohmann-json)) + - :octicons-rocket-24: The package is updated with every release. + - :octicons-person-24: Maintainer: [Axel Huebl](https://github.com/ax3l) + - :octicons-file-24: File issues at the [Spack issue tracker](https://github.com/spack/spack/issues) + - :octicons-question-24: [Spack website](https://spack.io) + +If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the +[`nlohmann-json` package](https://packages.spack.io/package.html?name=nlohmann-json) via + +```shell +spack install nlohmann-json +``` + +Please see the [Spack project](https://github.com/spack/spack) for any issues regarding the packaging. + +??? example + + 1. Create the following files: + + ```cmake title="CMakeLists.txt" + --8<-- "integration/spack/CMakeLists.txt" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/spack/example.cpp" + ``` + + 2. Install the library: + + ```sh + spack install nlohmann-json + ``` + + 3. Load the environment for your Spack-installed packages: + + ```sh + spack load nlohmann-json + ``` + + 4. Build the project with CMake: + + ```sh + cmake -S . -B build -DCMAKE_PREFIX_PATH=$(spack location -i nlohmann-json) + cmake --build build + ``` + +## Hunter + +!!! abstract "Summary" + + package: [**`nlohmann_json`**](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html) + + - :octicons-tag-24: Available versions: current version and older versions (see + [Hunter package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html)) + - :octicons-rocket-24: The package is updated with every release. + - :octicons-file-24: File issues at the [Hunter issue tracker](https://github.com/cpp-pm/hunter/issues) + - :octicons-question-24: [Hunter website](https://hunter.readthedocs.io/en/latest/) + +If you are using [Hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use +the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html) via + +```cmake +hunter_add_package(nlohmann_json) +``` + +Please see the Hunter project for any issues regarding the packaging. + +??? example + + 1. Create the following files: + + ```cmake title="CMakeLists.txt" + --8<-- "integration/hunter/CMakeLists.txt" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/hunter/example.cpp" + ``` + + 2. Download required files + + ```shell + mkdir cmake + wget https://raw.githubusercontent.com/cpp-pm/gate/master/cmake/HunterGate.cmake -O cmake/HunterGate.cmake + ``` + + 3. Build the project with CMake: + + ```shell + cmake -S . -B build + cmake --build build + ``` + +## vcpkg + +!!! abstract "Summary" + + package: [**`nlohmann-json`**](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) + + - [![Vcpkg package](https://repology.org/badge/version-for-repo/vcpkg/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + - :octicons-tag-24: Available versions: current version + - :octicons-rocket-24: The package is updated with every release. + - :octicons-file-24: File issues at the [vcpkg issue tracker](https://github.com/microsoft/vcpkg/issues) + - :octicons-question-24: [vcpkg website](https://vcpkg.io/) + +If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can +install the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) with + +```shell +vcpkg install nlohmann-json +``` + +and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging. + +??? example + + 1. Create the following files: + + ```cmake title="CMakeLists.txt" + --8<-- "integration/vcpkg/CMakeLists.txt" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/vcpkg/example.cpp" + ``` + + 2. Install package: + + ```sh + vcpkg install nlohmann-json + ``` + + 3. Build: + + ```sh + cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake + cmake --build build + ``` + +## cget + +!!! abstract "Summary" + + package: [**`nlohmann/json`**](https://github.com/pfultz2/cget-recipes/blob/master/recipes/nlohmann/json/package.txt) + + - :octicons-tag-24: Available versions: current version and older versions + - :octicons-rocket-24: The package is updated with every release. + - :octicons-file-24: File issues at the [cget issue tracker](https://github.com/pfultz2/cget-recipes/issues) + - :octicons-question-24: [cget website](https://cget.readthedocs.io/) + +If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest `master` version with + +```shell +cget install nlohmann/json +``` + +A specific version can be installed with `cget install nlohmann/json@v3.12.0`. Also, the multiple header version can be +installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`). + +??? example + + 1. Create the following files: + + ```cmake title="CMakeLists.txt" + --8<-- "integration/vcpkg/CMakeLists.txt" + ``` + + ```cpp title="example.cpp" + --8<-- "integration/vcpkg/example.cpp" + ``` + + 2. Initialize cget + + ```shell + cget init + ``` + + 3. Install the library + + ```shell + cget install nlohmann/json + ``` + + 4. Build + + ```shell + cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cget/cget/cget.cmake + cmake --build build + ``` + +## Swift Package Manager + +!!! abstract "Summary" + + package: **`nlohmann/json`** + + - :octicons-tag-24: Available versions: current version and older versions + - :octicons-rocket-24: The package is updated with every release. + - :octicons-file-24: File issues at the [library issue tracker](https://github.com/nlohmann/json/issues) + - :octicons-question-24: [Xcode documentation](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app) + +## NuGet + +!!! abstract "Summary" + + package: [**`nlohmann.json`**](https://www.nuget.org/packages/nlohmann.json/) + + - :octicons-tag-24: Available versions: current and previous versions + - :octicons-rocket-24: The package is updated with every release. + - :octicons-person-24: Maintainer: [Hani Kaabi](https://github.com/hnkb) + - :octicons-file-24: File issues at the [maintainer's issue tracker](https://github.com/hnkb/nlohmann-json-nuget/issues) + - :octicons-question-24: [NuGet website](https://www.nuget.org) + +If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/) +with + +```shell +dotnet add package nlohmann.json +``` + +??? example + + Probably the easiest way to use NuGet packages is through Visual Studio graphical interface. Right-click on a + project (any C++ project would do) in “Solution Explorer” and select “Manage NuGet Packages…” + + ![](nuget/nuget-search-package.png) + + Now you can click on “Browse” tab and find the package you like to install. + + ![](nuget/nuget-select-package.png) + + Most of the packages in NuGet gallery are .NET packages and would not be useful in a C++ project. Microsoft + recommends adding “native” and “nativepackage” tags to C++ NuGet packages to distinguish them, but even adding + “native” to search query would still show many .NET-only packages in the list. + + Nevertheless, after finding the package you want, click on “Install” button and accept confirmation dialogs. + After the package is successfully added to the projects, you should be able to build and execute the project + without the need for making any more changes to build settings. + + !!! note + + A few notes: + + - NuGet packages are installed per project and not system-wide. The header and binaries for the package are only + available to the project it is added to, and not other projects (obviously unless we add the package to those + projects as well) + - One of the many great things about your elegant work is that it is a header-only library, which makes + deployment very straightforward. In case of libraries which need binary deployment (`.lib`, `.dll` and `.pdb` + for debug info) the different binaries for each supported compiler version must be added to the NuGet package. + Some library creators cram binary versions for all supported Visual C++ compiler versions in the same package, + so a single package will support all compilers. Some others create a different package for each compiler + version (and you usually see things like “v140” or “vc141” in package name to clarify which VC++ compiler this + package supports). + - Packages can have dependency to other packages, and in this case, NuGet will install all dependencies as well + as the requested package recursively. + + **What happens behind the scenes** + + After you add a NuGet package, three changes occur in the project source directory. Of course, we could make these + changes manually instead of using GUI: + + ![](nuget/nuget-project-changes.png) + + 1. A `packages.config` file will be created (or updated to include the package name if one such file already + exists). This file contains a list of the packages required by this project (name and minimum version) and must + be added to the project source code repository, so if you move the source code to a new machine, MSBuild/NuGet + knows which packages it has to restore (which it does automatically before each build). + + ```xml + + + + + ``` + + 2. A `packages` folder which contains actual files in the packages (these are header and binary files required for + a successful build, plus a few metadata files). In case of this library for example, it contains `json.hpp`: + + ![](nuget/nuget-package-content.png) + + !!! note + + This directory should not be added to the project source code repository, as it will be restored before each + build by MSBuild/NuGet. If you go ahead and delete this folder, then build the project again, it will + magically re-appear! + + 3. Project MSBuild makefile (which for Visual C++ projects has a .vcxproj extension) will be updated to include + settings from the package. + + ![](nuget/nuget-project-makefile.png) + + The important bit for us here is line 170, which tells MSBuild to import settings from + `packages\nlohmann.json.3.5.0\build\native\nlohmann.json.targets` file. This is a file the package creator + created and added to the package (you can see it is one of the two files I created in this repository, the other + just contains package attributes like name and version number). What does it contain? + + For our header-only repository, the only setting we need is to add our include directory to the list of + `AdditionalIncludeDirectories`: + + ```xml + + + + + $(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories) + + + + ``` + + For libraries with binary files, we will need to add `.lib` files to linker inputs and add settings to copy + `.dll` and other redistributable files to output directory, if needed. + + There are other changes to the makefile as well: + + - Lines 165-167 add the `packages.config` as one of project files (so it is shown in Solution Explorer tree + view). It is added as None (no build action) and removing it wouldn’t affect build. + + - Lines 172-177 check to ensure the required packages are present. This will display a build error if package + directory is empty (for example when NuGet cannot restore packages because Internet connection is down). + Again, if you omit this section, the only change in build would be a more cryptic error message if build + fails. + + !!! note + + Changes to .vcxproj makefile should also be added to project source code repository. + + As you can see, the mechanism NuGet uses to modify project settings is through MSBuild makefiles, so using NuGet + with other build systems and compilers (like CMake) as a dependency manager is either impossible or more problematic + than useful. + +Please refer to [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) for +more information. + +## Conda + +!!! abstract "Summary" + + package: [**`nlohmann_json`**](https://anaconda.org/conda-forge/nlohmann_json) + + - ![](https://img.shields.io/conda/v/conda-forge/nlohmann_json) + - :octicons-tag-24: Available versions: current and previous versions + - :octicons-rocket-24: The package is updated with every release. + - :octicons-file-24: File issues at the [feedstock's issue tracker](https://github.com/conda-forge/nlohmann_json-feedstock/issues) + - :octicons-question-24: [Conda documentation](https://docs.conda.io/projects/conda/en/stable/user-guide/getting-started.html) + +If you are using [conda](https://conda.io/), you can use the package +[nlohmann_json](https://anaconda.org/conda-forge/nlohmann_json) from [conda-forge](https://conda-forge.org) executing + +```shell +conda install -c conda-forge nlohmann_json +``` + +??? example + + 1. Create the following file: + + ```cpp title="example.cpp" + --8<-- "integration/conda/example.cpp" + ``` + + 2. Create and activate an environment `json`: + + ```shell + conda create -n json + conda activate json + ``` + + 3. Install the package: + + ```shell + conda install -c conda-forge nlohmann_json + ``` + + 4. Build the code: + + ```shell + g++ -std=c++11 -I$(conda info --base)/envs/json/include example.cpp -o example + ``` + +## MSYS2 + +If you are using [MSYS2](http://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages. + +[![MSYS2 clang64 package](https://repology.org/badge/version-for-repo/msys2_clang64/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) +[![MSYS2 clangarm64 package](https://repology.org/badge/version-for-repo/msys2_clangarm64/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) +[![MSYS2 mingw package](https://repology.org/badge/version-for-repo/msys2_mingw/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) +[![MSYS2 ucrt64 package](https://repology.org/badge/version-for-repo/msys2_ucrt64/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + +:material-update: The [package](https://packages.msys2.org/base/mingw-w64-nlohmann-json) is updated automatically. + +## MacPorts + +!!! abstract "Summary" + + port: [**`nlohmann-json`**](https://ports.macports.org/port/nlohmann-json/) + + - [![MacPorts package](https://repology.org/badge/version-for-repo/macports/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + - :octicons-tag-24: Available versions: current version + - :octicons-rocket-24: The port is updated with every release. + - :octicons-file-24: File issues at the [MacPorts issue tracker](https://trac.macports.org/newticket?port=nlohmann-json) + - :octicons-question-24: [MacPorts website](https://www.macports.org) + +If you are using [MacPorts](https://ports.macports.org), execute + +```shell +sudo port install nlohmann-json +``` + +to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package. + +??? example "Example: Raw compilation" + + 1. Create the following file: + + ```cpp title="example.cpp" + --8<-- "integration/macports/example.cpp" + ``` + + 2. Install the package: + + ```sh + sudo port install nlohmann-json + ``` + + 3. Compile the code and pass the MacPorts prefix to the include path such that the library can be found: + + ```sh + c++ example.cpp -I/opt/local/include -std=c++11 -o example + ``` + +??? example "Example: CMake" + + 1. Create the following files: + + ```cpp title="example.cpp" + --8<-- "integration/homebrew/example.cpp" + ``` + + ```cmake title="CMakeLists.txt" + --8<-- "integration/homebrew/CMakeLists.txt" + ``` + + 2. Install the package: + + ```sh + sudo port install nlohmann-json + ``` + + 3. Compile the code: + + ```sh + cmake -S . -B build + cmake --build build + ``` + +## build2 + +!!! abstract "Summary" + + package: **`nlohmann-json`** + library target: **`nlohmann-json%lib{json}`** + available in package repositories: + - [`cppget.org` (recommended)](https://cppget.org/nlohmann-json) + - [package's sources (for advanced users)](https://github.com/build2-packaging/nlohmann-json/) + + - :octicons-tag-24: Available versions: current version and older versions since `3.7.3` (see [cppget.org](https://cppget.org/nlohmann-json)) + - :octicons-rocket-24: The package is maintained and published by the `build2` community in [this repository](https://github.com/build2-packaging/nlohmann-json/). + - :octicons-file-24: File issues at the [package source repository](https://github.com/build2-packaging/nlohmann-json/issues/) + - :octicons-question-24: [`build2` website](https://build2.org) + +Note: [`build2`](https://build2.org) should not be considered as a standalone package-manager. It is a build-system + package manager + project manager, a set of tools that work hand-in-hand. `build2`-based projects do not rely on existing `CMake` scripts and the build scripts defining the project's targets are specific to `build2`. + +To use this package in an existing [`build2`](https://build2.org) project, the general steps are: + + 1.
    Make the package available to download from a package repository that provides it. + + Your project's `repositories.manifest` specifies where the package manager will try to acquire packages by default. Make sure one of the repositories specified in this file provides `nlohmann-json` package. + The recommended open-source repository is [`cppget.org`](https://cppget.org/). + + If the project has been created using [`bdep new`](https://build2.org/bdep/doc/bdep-new.xhtml), `cppget.org` is already specified in `repositories.manifest` but commented, just uncomment these lines: + ``` + : + role: prerequisite + location: https://pkg.cppget.org/1/stable + ``` +
    + + 2.
    Add this package as dependency of your project. + + In your project's `manifest` add the dependency to the package using `depends: nlohmann-json`. You could also add some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps). + For example, to depend on the latest version available: + ``` + depends: nlohmann-json + ``` +
    + + + 3.
    Add this library as dependency of your target that uses it. + + In the `buildfile` defining the target that will use this library: + + - import the target `lib{json}` from the `nlohmann-json` package, for example: + ``` + import nljson = nlohmann-json%lib{json} + ``` + + - then add the library's target as requirement for your target using it, for example: + ``` + exe{example} : ... $nljson + ``` + +
    + + 4.
    Use the library in your project's code and build it. + + At this point, assuming your project is initialized in a build-configuration, any `b` or `bdep update` command that will update/build the project will also acquire the missing dependency automatically, then build it and link it with your target. + + If you just want to synchronize dependencies for all your configurations to download the ones you just added: + ``` + bdep sync -af + ``` +
    + +??? example "Example: from scratch, using `build2`'s [`bdep new` command](https://build2.org/bdep/doc/bdep-new.xhtml)" + + 1. Create a new executable project "example" (see [`bdep new` command details](https://build2.org/bdep/doc/bdep-new.xhtml) for the various options to create a new project): + + ```shell + bdep new example + ``` + + 2. Edit these files by replacing their content: + + - `example/repositories.manifest`: Enable acquiring packages from https://cppget.org by uncommenting the related lines: + + ```make title="project's `repositories.manifest`" + --8<-- "integration/build2/repositories.manifest" + ``` + + - `example/manifest`: Add the latest version of the `nlohmann-json` package as dependency to the project: + + ```make title="project's `manifest`" + --8<-- "integration/build2/manifest" + ``` + + - `example/example/buildfile`: import the library's target to be used as requirement for building the executable target `exe{example}`: + + ```make title="project's `buildfile`" + --8<-- "integration/build2/buildfile" + ``` + + - `example/example/example.cxx`: `bdep new` generates a "hello world" by default, replace it by this: + + ```cpp title="example.cxx" + --8<-- "integration/build2/example.cpp" + ``` + + - `example/example/testscript`: (optional) if you want to be able to test that executable's output is correct using `b test`: + + ```cpp title="`testscript` checking the output of the program" + --8<-- "integration/build2/testscript" + ``` + + + 3. Initialize the project in a default C/C++ build configuration directory, then build and test: + + ```shell + cd example/ + + # create default C/C++ build configuration in ../example-myconfig/, initialize the project in it (downloads it's dependencies in it too) + bdep init -C @myconfig cc + + # build only, + b + + # or build and test the executable's output, will only work if the `testscript` is correct + b test + + ``` + +## CPM.cmake + +!!! abstract "Summary" + + package: **`gh:nlohmann/json`** + + - :octicons-tag-24: Available versions: current and previous versions + - :octicons-rocket-24: The package is updated with every release. + - :octicons-file-24: File issues at the [CPM.cmake issue tracker](https://github.com/cpm-cmake/CPM.cmake/issues) + - :octicons-question-24: [CPM.cmake website](https://github.com/cpm-cmake/CPM.cmake) + +If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), add the +[CPM.cmake script](https://github.com/TheLartians/CPM.cmake#adding-cpm) and the following snippet to your CMake project: + +```cmake +CPMAddPackage("gh:nlohmann/json@3.12.0") +``` + +??? example + + 1. Create the following files: + + ```cpp title="example.cpp" + --8<-- "integration/cpm/example.cpp" + ``` + + ```cmake title="CMakeLists.txt" + --8<-- "integration/cpm/CMakeLists.txt" + ``` + + 2. Download CPM.cmake + + ```shell + mkdir -p cmake + wget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake + ``` + + 3. Build + + ```shell + cmake -S . -B build + cmake --build build + ``` + +## xmake + +!!! abstract "Summary" + + package: [**`nlohmann_json`**](https://github.com/xmake-io/xmake-repo/blob/master/packages/n/nlohmann_json/xmake.lua) + + - :octicons-tag-24: Available versions: current and previous versions + - :octicons-rocket-24: The package is updated with every release. + - :octicons-file-24: File issues at the [xmake issue tracker](https://github.com/xmake-io/xmake-repo/issues) + - :octicons-question-24: [xmake website](https://xmake.io/#/) + +??? example + + 1. Create the following files: + + ```cpp title="example.cpp" + --8<-- "integration/xmake/example.cpp" + ``` + + ```lua title="xmake.lua" + --8<-- "integration/xmake/xmake.lua" + ``` + + 2. Build + + ```shell + xmake + ``` + + 3. Run + + ```shell + xmake run + ``` + +* * * + +## Other package managers + +The library is also contained in many other package repositories: [![Packaging status](https://repology.org/badge/tiny-repos/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + +??? example "Package version overview" + + [![Packaging status](https://repology.org/badge/vertical-allrepos/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) + + +* * * + +## Buckaroo + +If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example). + +!!! warning + + The module is outdated as the respective [repository](https://github.com/buckaroo-pm/nlohmann-json) has not been + updated in years. + +## CocoaPods + +If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` +to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues +[here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open). + +![](https://img.shields.io/cocoapods/v/nlohmann_json) + +!!! warning + + The module is outdated as the respective [pod](https://cocoapods.org/pods/nlohmann_json) has not been updated in years. diff --git a/integration/package_managers/index.html b/integration/package_managers/index.html index e33d16f6c..9ee8d6d37 100644 --- a/integration/package_managers/index.html +++ b/integration/package_managers/index.html @@ -416,4 +416,4 @@ cmake --build build set_languages("cxx11")
  • Build

    xmake
     
  • Run

    xmake run
    -

  • Other package managers

    The library is also contained in many other package repositories: Packaging status

    Package version overview

    Packaging status


    Buckaroo

    If you are using Buckaroo, you can install this library's module with buckaroo add github.com/buckaroo-pm/nlohmann-json. There is a demo repo here.

    Warning

    The module is outdated as the respective repository has not been updated in years.

    CocoaPods

    If you are using CocoaPods, you can use the library by adding pod "nlohmann_json", '~>3.1.2' to your podfile (see an example). Please file issues here.

    Warning

    The module is outdated as the respective pod has not been updated in years.

    \ No newline at end of file +

    Other package managers

    The library is also contained in many other package repositories: Packaging status

    Package version overview

    Packaging status


    Buckaroo

    If you are using Buckaroo, you can install this library's module with buckaroo add github.com/buckaroo-pm/nlohmann-json. There is a demo repo here.

    Warning

    The module is outdated as the respective repository has not been updated in years.

    CocoaPods

    If you are using CocoaPods, you can use the library by adding pod "nlohmann_json", '~>3.1.2' to your podfile (see an example). Please file issues here.

    Warning

    The module is outdated as the respective pod has not been updated in years.

    \ No newline at end of file diff --git a/integration/package_managers/index.md b/integration/package_managers/index.md new file mode 100644 index 000000000..635c7194a --- /dev/null +++ b/integration/package_managers/index.md @@ -0,0 +1,1196 @@ +# Package Managers + +[**Homebrew**](#homebrew) `nlohmann-json`    [**Meson**](#meson) `nlohmann_json`    [**Bazel**](#bazel) `nlohmann_json`\ +[**Conan**](#conan) `nlohmann_json`    [**Spack**](#spack) `nlohmann-json`   [**Hunter**](#hunter) `nlohmann_json`\ +[**vcpkg**](#vcpkg) `nlohmann-json`   [**cget**](#cget) `nlohmann/json`    [**Swift Package Manager**](#swift-package-manager) `nlohmann/json`\ +[**NuGet**](#nuget) `nlohmann.json`    [**Conda**](#conda) `nlohmann_json`    [**MacPorts**](#macports) `nlohmann-json`\ +[**CPM.cmake**](#cpmcmake) `gh:nlohmann/json`    [**xmake**](#xmake) `nlohmann_json` + +## Running example + +Throughout this page, we will describe how to compile the example file `example.cpp` below. + +``` +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::setw(4) << json::meta() << std::endl; +} +``` + +When executed, this program should create output similar to + +``` +{ + "compiler": { + "c++": "201103", + "family": "gcc", + "version": "12.4.0" + }, + "copyright": "(C) 2013-2026 Niels Lohmann", + "name": "JSON for Modern C++", + "platform": "apple", + "url": "https://github.com/nlohmann/json", + "version": { + "major": 3, + "minor": 12, + "patch": 0, + "string": "3.12.0" + } +} +``` + +## Homebrew + +Summary + +formula: [**`nlohmann-json`**](https://formulae.brew.sh/formula/nlohmann-json) + +- Available versions: current version and development version (with `--HEAD` parameter) +- The formula is updated with every release. +- Maintainer: Niels Lohmann +- File issues at the [Homebrew issue tracker](https://github.com/Homebrew/homebrew-core/issues) +- [Homebrew website](https://brew.sh) + +If you are using [Homebrew](http://brew.sh), you can install the library with + +``` +brew install nlohmann-json +``` + +The header can be used directly in your code or via CMake. + +Example: Raw compilation + +1. Create the following file: + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Install the package: + + ``` + brew install nlohmann-json + ``` + +1. Compile the code and pass the Homebrew prefix to the include path such that the library can be found: + + ``` + c++ example.cpp -I$(brew --prefix nlohmann-json)/include -std=c++11 -o example + ``` + +Example: CMake + +1. Create the following files: + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + project(json_example) + + find_package(nlohmann_json CONFIG REQUIRED) + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + +1. Install the package: + + ``` + brew install nlohmann-json + ``` + +1. Compile the code and pass the Homebrew prefix to CMake to find installed packages via `find_package`: + + ``` + CMAKE_PREFIX_PATH=$(brew --prefix) cmake -S . -B build + cmake --build build + ``` + +## Meson + +Summary + +wrap: **`nlohmann_json`** + +- Available versions: current version and select older versions (see [WrapDB](https://mesonbuild.com/Wrapdb-projects.html)) +- The package is updated automatically from file [`meson.build`](https://github.com/nlohmann/json/blob/develop/meson.build). +- File issues at the [library issue tracker](https://github.com/nlohmann/json/issues) +- [Meson website](https://mesonbuild.com/index.html) + +If you are using the [Meson Build System](http://mesonbuild.com), add this source tree as a [meson subproject](https://mesonbuild.com/Subprojects.html#using-a-subproject). You may also use the `include.zip` published in this project's [Releases](https://github.com/nlohmann/json/releases) to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from [Meson WrapDB](https://mesonbuild.com/Wrapdb-projects.html), or use + +``` +meson wrap install nlohmann_json +``` + +Please see the Meson project for any issues regarding the packaging. + +The provided `meson.build` can also be used as an alternative to CMake for installing `nlohmann_json` system-wide in which case a pkg-config file is installed. To use it, have your build system require the `nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than using the subproject directly. + +Example: Wrap + +1. Create the following files: + + meson.build + + ``` + project('json_example', 'cpp', + version: '1.0', + default_options: ['cpp_std=c++11'] + ) + + dependency_json = dependency('nlohmann_json', required: true) + + executable('json_example', + sources: ['example.cpp'], + dependencies: [dependency_json], + install: true + ) + ``` + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Use the Meson WrapDB to fetch the nlohmann/json wrap: + + ``` + mkdir subprojects + meson wrap install nlohmann_json + ``` + +1. Build: + + ``` + meson setup build + meson compile -C build + ``` + +## Bazel + +Summary + +use `bazel_dep`, `git_override`, or `local_path_override` + +- Any version, that is available via [Bazel Central Registry](https://registry.bazel.build/modules/nlohmann_json) +- File issues at the [library issue tracker](https://github.com/nlohmann/json/issues) +- [Bazel website](https://bazel.build) + +This repository provides a [Bazel](https://bazel.build/) `MODULE.bazel` and a corresponding `BUILD.bazel` file. Therefore, this repository can be referenced within a `MODULE.bazel` by rules such as `archive_override`, `git_override`, or `local_path_override`. To use the library, you need to depend on the target `@nlohmann_json//:json` (i.e., via `deps` attribute). + +Example + +1. Create the following files: + + BUILD + + ``` + cc_binary( + name = "main", + srcs = ["example.cpp"], + deps = ["@nlohmann_json//:json"], + ) + ``` + + WORKSPACE + + ``` + bazel_dep(name = "nlohmann_json", version = "3.11.3.bcr.1") + ``` + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Build and run: + + ``` + bazel build //:main + bazel run //:main + ``` + +## Conan + +Summary + +recipe: [**`nlohmann_json`**](https://conan.io/center/recipes/nlohmann_json) + +- Available versions: current version and older versions (see [Conan Center](https://conan.io/center/recipes/nlohmann_json)) +- The package is updated automatically via [this recipe](https://github.com/conan-io/conan-center-index/tree/master/recipes/nlohmann_json). +- File issues at the [Conan Center issue tracker](https://github.com/conan-io/conan-center-index/issues) +- [Conan website](https://conan.io) + +If you are using [Conan](https://www.conan.io/) to manage your dependencies, merely add `nlohmann_json/x.y.z` to your `conanfile`'s requires, where `x.y.z` is the release version you want to use. + +Example + +1. Create the following files: + + Conanfile.txt + + ``` + [requires] + nlohmann_json/3.12.0 + + [generators] + CMakeToolchain + CMakeDeps + ``` + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + project(json_example) + + find_package(nlohmann_json REQUIRED) + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Call Conan: + + ``` + conan install . --output-folder=build --build=missing + ``` + +1. Build: + + ``` + cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" -DCMAKE_BUILD_TYPE=Release + cmake --build build + ``` + +## Spack + +Summary + +package: [**`nlohmann-json`**](https://packages.spack.io/package.html?name=nlohmann-json) + +- Available versions: current version and older versions (see [Spack package](https://packages.spack.io/package.html?name=nlohmann-json)) +- The package is updated with every release. +- Maintainer: [Axel Huebl](https://github.com/ax3l) +- File issues at the [Spack issue tracker](https://github.com/spack/spack/issues) +- [Spack website](https://spack.io) + +If you are using [Spack](https://www.spack.io/) to manage your dependencies, you can use the [`nlohmann-json` package](https://packages.spack.io/package.html?name=nlohmann-json) via + +``` +spack install nlohmann-json +``` + +Please see the [Spack project](https://github.com/spack/spack) for any issues regarding the packaging. + +Example + +1. Create the following files: + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + project(json_example) + + find_package(nlohmann_json REQUIRED) + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Install the library: + + ``` + spack install nlohmann-json + ``` + +1. Load the environment for your Spack-installed packages: + + ``` + spack load nlohmann-json + ``` + +1. Build the project with CMake: + + ``` + cmake -S . -B build -DCMAKE_PREFIX_PATH=$(spack location -i nlohmann-json) + cmake --build build + ``` + +## Hunter + +Summary + +package: [**`nlohmann_json`**](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html) + +- Available versions: current version and older versions (see [Hunter package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html)) +- The package is updated with every release. +- File issues at the [Hunter issue tracker](https://github.com/cpp-pm/hunter/issues) +- [Hunter website](https://hunter.readthedocs.io/en/latest/) + +If you are using [Hunter](https://github.com/cpp-pm/hunter) on your project for external dependencies, then you can use the [nlohmann_json package](https://hunter.readthedocs.io/en/latest/packages/pkg/nlohmann_json.html) via + +``` +hunter_add_package(nlohmann_json) +``` + +Please see the Hunter project for any issues regarding the packaging. + +Example + +1. Create the following files: + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + + include("cmake/HunterGate.cmake") + HunterGate( + URL "https://github.com/cpp-pm/hunter/archive/v0.23.297.tar.gz" + SHA1 "3319fe6a3b08090df7df98dee75134d68e2ef5a3" + ) + + project(json_example) + + hunter_add_package(nlohmann_json) + find_package(nlohmann_json CONFIG REQUIRED) + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Download required files + + ``` + mkdir cmake + wget https://raw.githubusercontent.com/cpp-pm/gate/master/cmake/HunterGate.cmake -O cmake/HunterGate.cmake + ``` + +1. Build the project with CMake: + + ``` + cmake -S . -B build + cmake --build build + ``` + +## vcpkg + +Summary + +package: [**`nlohmann-json`**](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) + +- Available versions: current version +- The package is updated with every release. +- File issues at the [vcpkg issue tracker](https://github.com/microsoft/vcpkg/issues) +- [vcpkg website](https://vcpkg.io/) + +If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can install the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json) with + +``` +vcpkg install nlohmann-json +``` + +and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging. + +Example + +1. Create the following files: + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + project(json_example) + + find_package(nlohmann_json CONFIG REQUIRED) + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Install package: + + ``` + vcpkg install nlohmann-json + ``` + +1. Build: + + ``` + cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake + cmake --build build + ``` + +## cget + +Summary + +package: [**`nlohmann/json`**](https://github.com/pfultz2/cget-recipes/blob/master/recipes/nlohmann/json/package.txt) + +- Available versions: current version and older versions +- The package is updated with every release. +- File issues at the [cget issue tracker](https://github.com/pfultz2/cget-recipes/issues) +- [cget website](https://cget.readthedocs.io/) + +If you are using [cget](http://cget.readthedocs.io/en/latest/), you can install the latest `master` version with + +``` +cget install nlohmann/json +``` + +A specific version can be installed with `cget install nlohmann/json@v3.12.0`. Also, the multiple header version can be installed by adding the `-DJSON_MultipleHeaders=ON` flag (i.e., `cget install nlohmann/json -DJSON_MultipleHeaders=ON`). + +Example + +1. Create the following files: + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + project(json_example) + + find_package(nlohmann_json CONFIG REQUIRED) + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Initialize cget + + ``` + cget init + ``` + +1. Install the library + + ``` + cget install nlohmann/json + ``` + +1. Build + + ``` + cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cget/cget/cget.cmake + cmake --build build + ``` + +## Swift Package Manager + +Summary + +package: **`nlohmann/json`** + +- Available versions: current version and older versions +- The package is updated with every release. +- File issues at the [library issue tracker](https://github.com/nlohmann/json/issues) +- [Xcode documentation](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app) + +## NuGet + +Summary + +package: [**`nlohmann.json`**](https://www.nuget.org/packages/nlohmann.json/) + +- Available versions: current and previous versions +- The package is updated with every release. +- Maintainer: [Hani Kaabi](https://github.com/hnkb) +- File issues at the [maintainer's issue tracker](https://github.com/hnkb/nlohmann-json-nuget/issues) +- [NuGet website](https://www.nuget.org) + +If you are using [NuGet](https://www.nuget.org), you can use the package [nlohmann.json](https://www.nuget.org/packages/nlohmann.json/) with + +``` +dotnet add package nlohmann.json +``` + +Example + +Probably the easiest way to use NuGet packages is through Visual Studio graphical interface. Right-click on a project (any C++ project would do) in “Solution Explorer” and select “Manage NuGet Packages…” + +Now you can click on “Browse” tab and find the package you like to install. + +Most of the packages in NuGet gallery are .NET packages and would not be useful in a C++ project. Microsoft recommends adding “native” and “nativepackage” tags to C++ NuGet packages to distinguish them, but even adding “native” to search query would still show many .NET-only packages in the list. + +Nevertheless, after finding the package you want, click on “Install” button and accept confirmation dialogs. After the package is successfully added to the projects, you should be able to build and execute the project without the need for making any more changes to build settings. + +Note + +A few notes: + +- NuGet packages are installed per project and not system-wide. The header and binaries for the package are only available to the project it is added to, and not other projects (obviously unless we add the package to those projects as well) +- One of the many great things about your elegant work is that it is a header-only library, which makes deployment very straightforward. In case of libraries which need binary deployment (`.lib`, `.dll` and `.pdb` for debug info) the different binaries for each supported compiler version must be added to the NuGet package. Some library creators cram binary versions for all supported Visual C++ compiler versions in the same package, so a single package will support all compilers. Some others create a different package for each compiler version (and you usually see things like “v140” or “vc141” in package name to clarify which VC++ compiler this package supports). +- Packages can have dependency to other packages, and in this case, NuGet will install all dependencies as well as the requested package recursively. + +**What happens behind the scenes** + +After you add a NuGet package, three changes occur in the project source directory. Of course, we could make these changes manually instead of using GUI: + +1. A `packages.config` file will be created (or updated to include the package name if one such file already exists). This file contains a list of the packages required by this project (name and minimum version) and must be added to the project source code repository, so if you move the source code to a new machine, MSBuild/NuGet knows which packages it has to restore (which it does automatically before each build). + + ``` + + + + + ``` + +1. A `packages` folder which contains actual files in the packages (these are header and binary files required for a successful build, plus a few metadata files). In case of this library for example, it contains `json.hpp`: + + Note + + This directory should not be added to the project source code repository, as it will be restored before each build by MSBuild/NuGet. If you go ahead and delete this folder, then build the project again, it will magically re-appear! + +1. Project MSBuild makefile (which for Visual C++ projects has a .vcxproj extension) will be updated to include settings from the package. + + The important bit for us here is line 170, which tells MSBuild to import settings from `packages\nlohmann.json.3.5.0\build\native\nlohmann.json.targets` file. This is a file the package creator created and added to the package (you can see it is one of the two files I created in this repository, the other just contains package attributes like name and version number). What does it contain? + + For our header-only repository, the only setting we need is to add our include directory to the list of `AdditionalIncludeDirectories`: + + ``` + + + + + $(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories) + + + + ``` + + For libraries with binary files, we will need to add `.lib` files to linker inputs and add settings to copy `.dll` and other redistributable files to output directory, if needed. + + There are other changes to the makefile as well: + + - Lines 165-167 add the `packages.config` as one of project files (so it is shown in Solution Explorer tree view). It is added as None (no build action) and removing it wouldn’t affect build. + - Lines 172-177 check to ensure the required packages are present. This will display a build error if package directory is empty (for example when NuGet cannot restore packages because Internet connection is down). Again, if you omit this section, the only change in build would be a more cryptic error message if build fails. + + Note + + Changes to .vcxproj makefile should also be added to project source code repository. + +As you can see, the mechanism NuGet uses to modify project settings is through MSBuild makefiles, so using NuGet with other build systems and compilers (like CMake) as a dependency manager is either impossible or more problematic than useful. + +Please refer to [this extensive description](https://github.com/nlohmann/json/issues/1132#issuecomment-452250255) for more information. + +## Conda + +Summary + +package: [**`nlohmann_json`**](https://anaconda.org/conda-forge/nlohmann_json) + +- Available versions: current and previous versions +- The package is updated with every release. +- File issues at the [feedstock's issue tracker](https://github.com/conda-forge/nlohmann_json-feedstock/issues) +- [Conda documentation](https://docs.conda.io/projects/conda/en/stable/user-guide/getting-started.html) + +If you are using [conda](https://conda.io/), you can use the package [nlohmann_json](https://anaconda.org/conda-forge/nlohmann_json) from [conda-forge](https://conda-forge.org) executing + +``` +conda install -c conda-forge nlohmann_json +``` + +Example + +1. Create the following file: + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Create and activate an environment `json`: + + ``` + conda create -n json + conda activate json + ``` + +1. Install the package: + + ``` + conda install -c conda-forge nlohmann_json + ``` + +1. Build the code: + + ``` + g++ -std=c++11 -I$(conda info --base)/envs/json/include example.cpp -o example + ``` + +## MSYS2 + +If you are using [MSYS2](http://www.msys2.org/), you can use the [mingw-w64-nlohmann-json](https://packages.msys2.org/base/mingw-w64-nlohmann-json) package, type `pacman -S mingw-w64-i686-nlohmann-json` or `pacman -S mingw-w64-x86_64-nlohmann-json` for installation. Please file issues [here](https://github.com/msys2/MINGW-packages/issues/new?title=%5Bnlohmann-json%5D) if you experience problems with the packages. + +The [package](https://packages.msys2.org/base/mingw-w64-nlohmann-json) is updated automatically. + +## MacPorts + +Summary + +port: [**`nlohmann-json`**](https://ports.macports.org/port/nlohmann-json/) + +- Available versions: current version +- The port is updated with every release. +- File issues at the [MacPorts issue tracker](https://trac.macports.org/newticket?port=nlohmann-json) +- [MacPorts website](https://www.macports.org) + +If you are using [MacPorts](https://ports.macports.org), execute + +``` +sudo port install nlohmann-json +``` + +to install the [nlohmann-json](https://ports.macports.org/port/nlohmann-json/) package. + +Example: Raw compilation + +1. Create the following file: + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + +1. Install the package: + + ``` + sudo port install nlohmann-json + ``` + +1. Compile the code and pass the MacPorts prefix to the include path such that the library can be found: + + ``` + c++ example.cpp -I/opt/local/include -std=c++11 -o example + ``` + +Example: CMake + +1. Create the following files: + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + project(json_example) + + find_package(nlohmann_json CONFIG REQUIRED) + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + +1. Install the package: + + ``` + sudo port install nlohmann-json + ``` + +1. Compile the code: + + ``` + cmake -S . -B build + cmake --build build + ``` + +## build2 + +Summary + +package: **`nlohmann-json`** library target: **`nlohmann-json%lib{json}`** available in package repositories: + +- [`cppget.org` (recommended)](https://cppget.org/nlohmann-json) + +- [package's sources (for advanced users)](https://github.com/build2-packaging/nlohmann-json/) + +- Available versions: current version and older versions since `3.7.3` (see [cppget.org](https://cppget.org/nlohmann-json)) + +- The package is maintained and published by the `build2` community in [this repository](https://github.com/build2-packaging/nlohmann-json/). + +- File issues at the [package source repository](https://github.com/build2-packaging/nlohmann-json/issues/) + +- [`build2` website](https://build2.org) + +Note: [`build2`](https://build2.org) should not be considered as a standalone package-manager. It is a build-system + package manager + project manager, a set of tools that work hand-in-hand. `build2`-based projects do not rely on existing `CMake` scripts and the build scripts defining the project's targets are specific to `build2`. + +To use this package in an existing [`build2`](https://build2.org) project, the general steps are: + +1. Make the package available to download from a package repository that provides it. + + Your project's `repositories.manifest` specifies where the package manager will try to acquire packages by default. Make sure one of the repositories specified in this file provides `nlohmann-json` package. The recommended open-source repository is [`cppget.org`](https://cppget.org/). + + If the project has been created using [`bdep new`](https://build2.org/bdep/doc/bdep-new.xhtml), `cppget.org` is already specified in `repositories.manifest` but commented, just uncomment these lines: + + ``` + : + role: prerequisite + location: https://pkg.cppget.org/1/stable + ``` + +1. Add this package as dependency of your project. + + In your project's `manifest` add the dependency to the package using `depends: nlohmann-json`. You could also add some [version constraints](https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps). For example, to depend on the latest version available: + + ``` + depends: nlohmann-json + ``` + +1. Add this library as dependency of your target that uses it. + + In the `buildfile` defining the target that will use this library: + + ```` + - import the target `lib{json}` from the `nlohmann-json` package, for example: + ``` + import nljson = nlohmann-json%lib{json} + ``` + + - then add the library's target as requirement for your target using it, for example: + ``` + exe{example} : ... $nljson + ``` + ```` + +1. Use the library in your project's code and build it. + + At this point, assuming your project is initialized in a build-configuration, any `b` or `bdep update` command that will update/build the project will also acquire the missing dependency automatically, then build it and link it with your target. + + If you just want to synchronize dependencies for all your configurations to download the ones you just added: + + ``` + bdep sync -af + ``` + +Example: from scratch, using `build2`'s [`bdep new` command](https://build2.org/bdep/doc/bdep-new.xhtml) + +1. Create a new executable project "example" (see [`bdep new` command details](https://build2.org/bdep/doc/bdep-new.xhtml) for the various options to create a new project): + + ``` + bdep new example + ``` + +1. Edit these files by replacing their content: + + - `example/repositories.manifest`: Enable acquiring packages from by uncommenting the related lines: + + project's `repositories.manifest` + + ``` + : 1 + summary: example project repository + + : + role: prerequisite + location: https://pkg.cppget.org/1/stable + #trust: ... + + #: + #role: prerequisite + #location: https://git.build2.org/hello/libhello.git + ``` + + - `example/manifest`: Add the latest version of the `nlohmann-json` package as dependency to the project: + + project's `manifest` + + ``` + name: example + version: 0.1.0-a.0.z + language: c++ + summary: example C++ executable + license: other: proprietary ; Not free/open source. + description-file: README.md + url: https://example.org/example + email: your@emailprovider.com + #build-error-email: your@emailprovider.com + depends: * build2 >= 0.16.0 + depends: * bpkg >= 0.16.0 + #depends: libhello ^1.0.0 + + depends: nlohmann-json + ``` + + - `example/example/buildfile`: import the library's target to be used as requirement for building the executable target `exe{example}`: + + project's `buildfile` + + ``` + libs = + import libs = nlohmann-json%lib{json} + + exe{example}: {hxx ixx txx cxx}{**} $libs testscript + + cxx.poptions =+ "-I$out_root" "-I$src_root" + ``` + + - `example/example/example.cxx`: `bdep new` generates a "hello world" by default, replace it by this: + + example.cxx + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + + - `example/example/testscript`: (optional) if you want to be able to test that executable's output is correct using `b test`: + + `testscript` checking the output of the program + + ``` + : json basics + : + $* >>~/EOO/ + { + "compiler": { + / "c\+\+": "\d+",/ + / "family": "[\w\d]+",/ + / "version": \d+/ + }, + / "copyright": "\(C\) 2013-\d+ Niels Lohmann",/ + "name": "JSON for Modern C++", + / "platform": "[\w\d]+",/ + "url": "https://github.com/nlohmann/json", + "version": { + "major": 3, + / "minor": \d+,/ + / "patch": \d+,/ + / "string": "3\.\d+\.\d+"/ + } + } + EOO + ``` + +1. Initialize the project in a default C/C++ build configuration directory, then build and test: + + ``` + cd example/ + + # create default C/C++ build configuration in ../example-myconfig/, initialize the project in it (downloads it's dependencies in it too) + bdep init -C @myconfig cc + + # build only, + b + + # or build and test the executable's output, will only work if the `testscript` is correct + b test + ``` + +## CPM.cmake + +Summary + +package: **`gh:nlohmann/json`** + +- Available versions: current and previous versions +- The package is updated with every release. +- File issues at the [CPM.cmake issue tracker](https://github.com/cpm-cmake/CPM.cmake/issues) +- [CPM.cmake website](https://github.com/cpm-cmake/CPM.cmake) + +If you are using [`CPM.cmake`](https://github.com/TheLartians/CPM.cmake), add the [CPM.cmake script](https://github.com/TheLartians/CPM.cmake#adding-cpm) and the following snippet to your CMake project: + +``` +CPMAddPackage("gh:nlohmann/json@3.12.0") +``` + +Example + +1. Create the following files: + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + + CMakeLists.txt + + ``` + cmake_minimum_required(VERSION 3.15) + project(json_example) + + include(${CMAKE_SOURCE_DIR}/cmake/CPM.cmake) + + CPMAddPackage("gh:nlohmann/json@3.12.0") + + add_executable(json_example example.cpp) + target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) + ``` + +1. Download CPM.cmake + + ``` + mkdir -p cmake + wget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake + ``` + +1. Build + + ``` + cmake -S . -B build + cmake --build build + ``` + +## xmake + +Summary + +package: [**`nlohmann_json`**](https://github.com/xmake-io/xmake-repo/blob/master/packages/n/nlohmann_json/xmake.lua) + +- Available versions: current and previous versions +- The package is updated with every release. +- File issues at the [xmake issue tracker](https://github.com/xmake-io/xmake-repo/issues) +- [xmake website](https://xmake.io/#/) + +Example + +1. Create the following files: + + example.cpp + + ``` + #include + #include + #include + + using json = nlohmann::json; + + int main() + { + std::cout << std::setw(4) << json::meta() << std::endl; + } + ``` + + xmake.lua + + ``` + add_requires("nlohmann_json") + + add_rules("mode.debug", "mode.release") + target("xm") + set_kind("binary") + add_files("example.cpp") + add_packages("nlohmann_json") + set_languages("cxx11") + ``` + +1. Build + + ``` + xmake + ``` + +1. Run + + ``` + xmake run + ``` + +______________________________________________________________________ + +## Other package managers + +The library is also contained in many other package repositories: + +Package version overview + +______________________________________________________________________ + +## Buckaroo + +If you are using [Buckaroo](https://buckaroo.pm), you can install this library's module with `buckaroo add github.com/buckaroo-pm/nlohmann-json`. There is a demo repo [here](https://github.com/njlr/buckaroo-nholmann-json-example). + +Warning + +The module is outdated as the respective [repository](https://github.com/buckaroo-pm/nlohmann-json) has not been updated in years. + +## CocoaPods + +If you are using [CocoaPods](https://cocoapods.org), you can use the library by adding pod `"nlohmann_json", '~>3.1.2'` to your podfile (see [an example](https://bitbucket.org/benman/nlohmann_json-cocoapod/src/master/)). Please file issues [here](https://bitbucket.org/benman/nlohmann_json-cocoapod/issues?status=new&status=open). + +Warning + +The module is outdated as the respective [pod](https://cocoapods.org/pods/nlohmann_json) has not been updated in years. diff --git a/integration/pkg-config.md b/integration/pkg-config.md new file mode 100644 index 000000000..429d0dea9 --- /dev/null +++ b/integration/pkg-config.md @@ -0,0 +1,13 @@ +# Pkg-config + +If you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed: + +```sh +pkg-config nlohmann_json --cflags +``` + +Users of the [Meson build system](package_managers.md#meson) will also be able to use a system-wide library, which will be found by `pkg-config`: + +```meson +json = dependency('nlohmann_json', required: true) +``` diff --git a/integration/pkg-config/index.html b/integration/pkg-config/index.html index fd4b62023..26824d8a4 100644 --- a/integration/pkg-config/index.html +++ b/integration/pkg-config/index.html @@ -1,3 +1,3 @@ Pkg-config - JSON for Modern C++

    Pkg-config

    If you are using bare Makefiles, you can use pkg-config to generate the include flags that point to where the library is installed:

    pkg-config nlohmann_json --cflags
     

    Users of the Meson build system will also be able to use a system-wide library, which will be found by pkg-config:

    json = dependency('nlohmann_json', required: true)
    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/integration/pkg-config/index.md b/integration/pkg-config/index.md new file mode 100644 index 000000000..c8f21f0cb --- /dev/null +++ b/integration/pkg-config/index.md @@ -0,0 +1,13 @@ +# Pkg-config + +If you are using bare Makefiles, you can use `pkg-config` to generate the include flags that point to where the library is installed: + +``` +pkg-config nlohmann_json --cflags +``` + +Users of the [Meson build system](https://json.nlohmann.me/integration/package_managers/#meson) will also be able to use a system-wide library, which will be found by `pkg-config`: + +``` +json = dependency('nlohmann_json', required: true) +``` diff --git a/llms.txt b/llms.txt new file mode 100644 index 000000000..d2505f2e6 --- /dev/null +++ b/llms.txt @@ -0,0 +1,271 @@ +# JSON for Modern C++ + +JSON for Modern C++ is a C++11 header-only library implementing a JSON value type with an STL-like API, JSON Pointer/Patch, CBOR/MessagePack/ BSON/UBJSON/BJData binary format support, and a SAX-style parser interface. + + +## Home + +- [JSON for Modern C++](https://json.nlohmann.me/index.md) +- [Architecture](https://json.nlohmann.me/home/architecture/index.md) +- [Customers](https://json.nlohmann.me/home/customers/index.md) +- [Design goals](https://json.nlohmann.me/home/design_goals/index.md) +- [Exceptions](https://json.nlohmann.me/home/exceptions/index.md) +- [FAQ](https://json.nlohmann.me/home/faq/index.md) +- [License](https://json.nlohmann.me/home/license/index.md) +- [Releases](https://json.nlohmann.me/home/releases/index.md) +- [Sponsors](https://json.nlohmann.me/home/sponsors/index.md) + +## Features + +- [Features](https://json.nlohmann.me/features/index.md) +- [Arbitrary Type Conversions](https://json.nlohmann.me/features/arbitrary_types/index.md) +- [Runtime Assertions](https://json.nlohmann.me/features/assertions/index.md) +- [Binary Values](https://json.nlohmann.me/features/binary_values/index.md) +- [Comments](https://json.nlohmann.me/features/comments/index.md) +- [Converting values](https://json.nlohmann.me/features/conversions/index.md) +- [Creating JSON values](https://json.nlohmann.me/features/creating_values/index.md) +- [Specializing enum conversion](https://json.nlohmann.me/features/enum_conversion/index.md) +- [Iterators](https://json.nlohmann.me/features/iterators/index.md) +- [JSON Patch and Diff](https://json.nlohmann.me/features/json_patch/index.md) +- [JSON Pointer](https://json.nlohmann.me/features/json_pointer/index.md) +- [Supported Macros](https://json.nlohmann.me/features/macros/index.md) +- [JSON Merge Patch](https://json.nlohmann.me/features/merge_patch/index.md) +- [Modifying values](https://json.nlohmann.me/features/modifying_values/index.md) +- [Modules](https://json.nlohmann.me/features/modules/index.md) +- [nlohmann Namespace](https://json.nlohmann.me/features/namespace/index.md) +- [Object Order](https://json.nlohmann.me/features/object_order/index.md) +- [Serialization](https://json.nlohmann.me/features/serialization/index.md) +- [Trailing Commas](https://json.nlohmann.me/features/trailing_commas/index.md) +- [Binary Formats](https://json.nlohmann.me/features/binary_formats/index.md) +- [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md) +- [BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md) +- [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md) +- [MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md) +- [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) +- [Element Access](https://json.nlohmann.me/features/element_access/index.md) +- [Checked access: at](https://json.nlohmann.me/features/element_access/checked_access/index.md) +- [Access with default value: value](https://json.nlohmann.me/features/element_access/default_value/index.md) +- [Unchecked access: operator[]](https://json.nlohmann.me/features/element_access/unchecked_access/index.md) +- [Parsing](https://json.nlohmann.me/features/parsing/index.md) +- [JSON Lines](https://json.nlohmann.me/features/parsing/json_lines/index.md) +- [Parsing and Exceptions](https://json.nlohmann.me/features/parsing/parse_exceptions/index.md) +- [Parser Callbacks](https://json.nlohmann.me/features/parsing/parser_callbacks/index.md) +- [SAX Interface](https://json.nlohmann.me/features/parsing/sax_interface/index.md) +- [Types](https://json.nlohmann.me/features/types/index.md) +- [Number Handling](https://json.nlohmann.me/features/types/number_handling/index.md) + +## Integration + +- [Header only](https://json.nlohmann.me/integration/index.md) +- [CMake](https://json.nlohmann.me/integration/cmake/index.md) +- [Migration Guide](https://json.nlohmann.me/integration/migration_guide/index.md) +- [Package Managers](https://json.nlohmann.me/integration/package_managers/index.md) +- [Pkg-config](https://json.nlohmann.me/integration/pkg-config/index.md) + +## API Documentation + +- [json](https://json.nlohmann.me/api/json/index.md) +- [operator>>(basic_json)](https://json.nlohmann.me/api/operator_gtgt/index.md) +- [operator""_json](https://json.nlohmann.me/api/operator_literal_json/index.md) +- [operator""_json_pointer](https://json.nlohmann.me/api/operator_literal_json_pointer/index.md) +- [operator<<(basic_json), operator<<(json_pointer)](https://json.nlohmann.me/api/operator_ltlt/index.md) +- [ordered_json](https://json.nlohmann.me/api/ordered_json/index.md) +- [ordered_map](https://json.nlohmann.me/api/ordered_map/index.md) +- [Overview](https://json.nlohmann.me/api/adl_serializer/index.md) +- [from_json](https://json.nlohmann.me/api/adl_serializer/from_json/index.md) +- [to_json](https://json.nlohmann.me/api/adl_serializer/to_json/index.md) +- [Overview](https://json.nlohmann.me/api/basic_json/index.md) +- [accept](https://json.nlohmann.me/api/basic_json/accept/index.md) +- [array](https://json.nlohmann.me/api/basic_json/array/index.md) +- [array_t](https://json.nlohmann.me/api/basic_json/array_t/index.md) +- [at](https://json.nlohmann.me/api/basic_json/at/index.md) +- [back](https://json.nlohmann.me/api/basic_json/back/index.md) +- [(Constructor)](https://json.nlohmann.me/api/basic_json/basic_json/index.md) +- [begin](https://json.nlohmann.me/api/basic_json/begin/index.md) +- [binary](https://json.nlohmann.me/api/basic_json/binary/index.md) +- [binary_t](https://json.nlohmann.me/api/basic_json/binary_t/index.md) +- [boolean_t](https://json.nlohmann.me/api/basic_json/boolean_t/index.md) +- [cbegin](https://json.nlohmann.me/api/basic_json/cbegin/index.md) +- [cbor_tag_handler_t](https://json.nlohmann.me/api/basic_json/cbor_tag_handler_t/index.md) +- [cend](https://json.nlohmann.me/api/basic_json/cend/index.md) +- [clear](https://json.nlohmann.me/api/basic_json/clear/index.md) +- [contains](https://json.nlohmann.me/api/basic_json/contains/index.md) +- [count](https://json.nlohmann.me/api/basic_json/count/index.md) +- [crbegin](https://json.nlohmann.me/api/basic_json/crbegin/index.md) +- [crend](https://json.nlohmann.me/api/basic_json/crend/index.md) +- [default_object_comparator_t](https://json.nlohmann.me/api/basic_json/default_object_comparator_t/index.md) +- [diff](https://json.nlohmann.me/api/basic_json/diff/index.md) +- [dump](https://json.nlohmann.me/api/basic_json/dump/index.md) +- [emplace](https://json.nlohmann.me/api/basic_json/emplace/index.md) +- [emplace_back](https://json.nlohmann.me/api/basic_json/emplace_back/index.md) +- [empty](https://json.nlohmann.me/api/basic_json/empty/index.md) +- [end](https://json.nlohmann.me/api/basic_json/end/index.md) +- [end_pos](https://json.nlohmann.me/api/basic_json/end_pos/index.md) +- [erase](https://json.nlohmann.me/api/basic_json/erase/index.md) +- [error_handler_t](https://json.nlohmann.me/api/basic_json/error_handler_t/index.md) +- [exception](https://json.nlohmann.me/api/basic_json/exception/index.md) +- [find](https://json.nlohmann.me/api/basic_json/find/index.md) +- [flatten](https://json.nlohmann.me/api/basic_json/flatten/index.md) +- [format_as](https://json.nlohmann.me/api/basic_json/format_as/index.md) +- [from_bjdata](https://json.nlohmann.me/api/basic_json/from_bjdata/index.md) +- [from_bson](https://json.nlohmann.me/api/basic_json/from_bson/index.md) +- [from_cbor](https://json.nlohmann.me/api/basic_json/from_cbor/index.md) +- [from_msgpack](https://json.nlohmann.me/api/basic_json/from_msgpack/index.md) +- [from_ubjson](https://json.nlohmann.me/api/basic_json/from_ubjson/index.md) +- [front](https://json.nlohmann.me/api/basic_json/front/index.md) +- [get](https://json.nlohmann.me/api/basic_json/get/index.md) +- [get_allocator](https://json.nlohmann.me/api/basic_json/get_allocator/index.md) +- [get_binary](https://json.nlohmann.me/api/basic_json/get_binary/index.md) +- [get_ptr](https://json.nlohmann.me/api/basic_json/get_ptr/index.md) +- [get_ref](https://json.nlohmann.me/api/basic_json/get_ref/index.md) +- [get_to](https://json.nlohmann.me/api/basic_json/get_to/index.md) +- [input_format_t](https://json.nlohmann.me/api/basic_json/input_format_t/index.md) +- [insert](https://json.nlohmann.me/api/basic_json/insert/index.md) +- [invalid_iterator](https://json.nlohmann.me/api/basic_json/invalid_iterator/index.md) +- [is_array](https://json.nlohmann.me/api/basic_json/is_array/index.md) +- [is_binary](https://json.nlohmann.me/api/basic_json/is_binary/index.md) +- [is_boolean](https://json.nlohmann.me/api/basic_json/is_boolean/index.md) +- [is_discarded](https://json.nlohmann.me/api/basic_json/is_discarded/index.md) +- [is_null](https://json.nlohmann.me/api/basic_json/is_null/index.md) +- [is_number](https://json.nlohmann.me/api/basic_json/is_number/index.md) +- [is_number_float](https://json.nlohmann.me/api/basic_json/is_number_float/index.md) +- [is_number_integer](https://json.nlohmann.me/api/basic_json/is_number_integer/index.md) +- [is_number_unsigned](https://json.nlohmann.me/api/basic_json/is_number_unsigned/index.md) +- [is_object](https://json.nlohmann.me/api/basic_json/is_object/index.md) +- [is_primitive](https://json.nlohmann.me/api/basic_json/is_primitive/index.md) +- [is_string](https://json.nlohmann.me/api/basic_json/is_string/index.md) +- [is_structured](https://json.nlohmann.me/api/basic_json/is_structured/index.md) +- [items](https://json.nlohmann.me/api/basic_json/items/index.md) +- [json_base_class_t](https://json.nlohmann.me/api/basic_json/json_base_class_t/index.md) +- [json_serializer](https://json.nlohmann.me/api/basic_json/json_serializer/index.md) +- [max_size](https://json.nlohmann.me/api/basic_json/max_size/index.md) +- [merge_patch](https://json.nlohmann.me/api/basic_json/merge_patch/index.md) +- [meta](https://json.nlohmann.me/api/basic_json/meta/index.md) +- [number_float_t](https://json.nlohmann.me/api/basic_json/number_float_t/index.md) +- [number_integer_t](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) +- [number_unsigned_t](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) +- [object](https://json.nlohmann.me/api/basic_json/object/index.md) +- [object_comparator_t](https://json.nlohmann.me/api/basic_json/object_comparator_t/index.md) +- [object_t](https://json.nlohmann.me/api/basic_json/object_t/index.md) +- [operator+=](https://json.nlohmann.me/api/basic_json/operator+=/index.md) +- [operator=](https://json.nlohmann.me/api/basic_json/operator=/index.md) +- [operator[]](https://json.nlohmann.me/api/basic_json/operator[]/index.md) +- [operator ValueType](https://json.nlohmann.me/api/basic_json/operator_ValueType/index.md) +- [operator==](https://json.nlohmann.me/api/basic_json/operator_eq/index.md) +- [operator>=](https://json.nlohmann.me/api/basic_json/operator_ge/index.md) +- [operator>](https://json.nlohmann.me/api/basic_json/operator_gt/index.md) +- [operator<=](https://json.nlohmann.me/api/basic_json/operator_le/index.md) +- [operator<](https://json.nlohmann.me/api/basic_json/operator_lt/index.md) +- [operator!=](https://json.nlohmann.me/api/basic_json/operator_ne/index.md) +- [operator<=>](https://json.nlohmann.me/api/basic_json/operator_spaceship/index.md) +- [operator value_t](https://json.nlohmann.me/api/basic_json/operator_value_t/index.md) +- [other_error](https://json.nlohmann.me/api/basic_json/other_error/index.md) +- [out_of_range](https://json.nlohmann.me/api/basic_json/out_of_range/index.md) +- [parse](https://json.nlohmann.me/api/basic_json/parse/index.md) +- [parse_error](https://json.nlohmann.me/api/basic_json/parse_error/index.md) +- [parse_event_t](https://json.nlohmann.me/api/basic_json/parse_event_t/index.md) +- [parser_callback_t](https://json.nlohmann.me/api/basic_json/parser_callback_t/index.md) +- [patch](https://json.nlohmann.me/api/basic_json/patch/index.md) +- [patch_inplace](https://json.nlohmann.me/api/basic_json/patch_inplace/index.md) +- [push_back](https://json.nlohmann.me/api/basic_json/push_back/index.md) +- [rbegin](https://json.nlohmann.me/api/basic_json/rbegin/index.md) +- [rend](https://json.nlohmann.me/api/basic_json/rend/index.md) +- [sax_parse](https://json.nlohmann.me/api/basic_json/sax_parse/index.md) +- [size](https://json.nlohmann.me/api/basic_json/size/index.md) +- [start_pos](https://json.nlohmann.me/api/basic_json/start_pos/index.md) +- [std::formatter<basic_json>](https://json.nlohmann.me/api/basic_json/std_formatter/index.md) +- [std::hash<basic_json>](https://json.nlohmann.me/api/basic_json/std_hash/index.md) +- [std::swap<basic_json>](https://json.nlohmann.me/api/basic_json/std_swap/index.md) +- [string_t](https://json.nlohmann.me/api/basic_json/string_t/index.md) +- [swap](https://json.nlohmann.me/api/basic_json/swap/index.md) +- [to_bjdata](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) +- [to_bson](https://json.nlohmann.me/api/basic_json/to_bson/index.md) +- [to_cbor](https://json.nlohmann.me/api/basic_json/to_cbor/index.md) +- [to_msgpack](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) +- [to_string](https://json.nlohmann.me/api/basic_json/to_string/index.md) +- [to_ubjson](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) +- [type](https://json.nlohmann.me/api/basic_json/type/index.md) +- [type_error](https://json.nlohmann.me/api/basic_json/type_error/index.md) +- [type_name](https://json.nlohmann.me/api/basic_json/type_name/index.md) +- [unflatten](https://json.nlohmann.me/api/basic_json/unflatten/index.md) +- [update](https://json.nlohmann.me/api/basic_json/update/index.md) +- [value](https://json.nlohmann.me/api/basic_json/value/index.md) +- [value_t](https://json.nlohmann.me/api/basic_json/value_t/index.md) +- [(Destructor)](https://json.nlohmann.me/api/basic_json/~basic_json/index.md) +- [Overview](https://json.nlohmann.me/api/byte_container_with_subtype/index.md) +- [(constructor)](https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/index.md) +- [clear_subtype](https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/index.md) +- [has_subtype](https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/index.md) +- [set_subtype](https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/index.md) +- [subtype](https://json.nlohmann.me/api/byte_container_with_subtype/subtype/index.md) +- [Overview](https://json.nlohmann.me/api/json_pointer/index.md) +- [back](https://json.nlohmann.me/api/json_pointer/back/index.md) +- [empty](https://json.nlohmann.me/api/json_pointer/empty/index.md) +- [front](https://json.nlohmann.me/api/json_pointer/front/index.md) +- [(Constructor)](https://json.nlohmann.me/api/json_pointer/json_pointer/index.md) +- [operator==](https://json.nlohmann.me/api/json_pointer/operator_eq/index.md) +- [operator!=](https://json.nlohmann.me/api/json_pointer/operator_ne/index.md) +- [operator/](https://json.nlohmann.me/api/json_pointer/operator_slash/index.md) +- [operator/=](https://json.nlohmann.me/api/json_pointer/operator_slasheq/index.md) +- [operator string_t](https://json.nlohmann.me/api/json_pointer/operator_string_t/index.md) +- [parent_pointer](https://json.nlohmann.me/api/json_pointer/parent_pointer/index.md) +- [pop_back](https://json.nlohmann.me/api/json_pointer/pop_back/index.md) +- [pop_front](https://json.nlohmann.me/api/json_pointer/pop_front/index.md) +- [push_back](https://json.nlohmann.me/api/json_pointer/push_back/index.md) +- [push_front](https://json.nlohmann.me/api/json_pointer/push_front/index.md) +- [string_t](https://json.nlohmann.me/api/json_pointer/string_t/index.md) +- [to_string](https://json.nlohmann.me/api/json_pointer/to_string/index.md) +- [Overview](https://json.nlohmann.me/api/json_sax/index.md) +- [binary](https://json.nlohmann.me/api/json_sax/binary/index.md) +- [boolean](https://json.nlohmann.me/api/json_sax/boolean/index.md) +- [end_array](https://json.nlohmann.me/api/json_sax/end_array/index.md) +- [end_object](https://json.nlohmann.me/api/json_sax/end_object/index.md) +- [key](https://json.nlohmann.me/api/json_sax/key/index.md) +- [null](https://json.nlohmann.me/api/json_sax/null/index.md) +- [number_float](https://json.nlohmann.me/api/json_sax/number_float/index.md) +- [number_integer](https://json.nlohmann.me/api/json_sax/number_integer/index.md) +- [number_unsigned](https://json.nlohmann.me/api/json_sax/number_unsigned/index.md) +- [parse_error](https://json.nlohmann.me/api/json_sax/parse_error/index.md) +- [start_array](https://json.nlohmann.me/api/json_sax/start_array/index.md) +- [start_object](https://json.nlohmann.me/api/json_sax/start_object/index.md) +- [string](https://json.nlohmann.me/api/json_sax/string/index.md) +- [Overview](https://json.nlohmann.me/api/macros/index.md) +- [JSON_ASSERT](https://json.nlohmann.me/api/macros/json_assert/index.md) +- [JSON_BRACE_INIT_COPY_SEMANTICS](https://json.nlohmann.me/api/macros/json_brace_init_copy_semantics/index.md) +- [JSON_DIAGNOSTIC_POSITIONS](https://json.nlohmann.me/api/macros/json_diagnostic_positions/index.md) +- [JSON_DIAGNOSTICS](https://json.nlohmann.me/api/macros/json_diagnostics/index.md) +- [JSON_DISABLE_ENUM_SERIALIZATION](https://json.nlohmann.me/api/macros/json_disable_enum_serialization/index.md) +- [JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20](https://json.nlohmann.me/api/macros/json_has_cpp_11/index.md) +- [JSON_HAS_EXPERIMENTAL_FILESYSTEM, JSON_HAS_FILESYSTEM](https://json.nlohmann.me/api/macros/json_has_filesystem/index.md) +- [JSON_HAS_RANGES](https://json.nlohmann.me/api/macros/json_has_ranges/index.md) +- [JSON_HAS_STATIC_RTTI](https://json.nlohmann.me/api/macros/json_has_static_rtti/index.md) +- [JSON_HAS_STD_FORMAT](https://json.nlohmann.me/api/macros/json_has_std_format/index.md) +- [JSON_HAS_THREE_WAY_COMPARISON](https://json.nlohmann.me/api/macros/json_has_three_way_comparison/index.md) +- [JSON_NO_IO](https://json.nlohmann.me/api/macros/json_no_io/index.md) +- [JSON_NOEXCEPTION](https://json.nlohmann.me/api/macros/json_noexception/index.md) +- [JSON_SKIP_LIBRARY_VERSION_CHECK](https://json.nlohmann.me/api/macros/json_skip_library_version_check/index.md) +- [JSON_SKIP_UNSUPPORTED_COMPILER_CHECK](https://json.nlohmann.me/api/macros/json_skip_unsupported_compiler_check/index.md) +- [JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER](https://json.nlohmann.me/api/macros/json_throw_user/index.md) +- [JSON_USE_GLOBAL_UDLS](https://json.nlohmann.me/api/macros/json_use_global_udls/index.md) +- [JSON_USE_IMPLICIT_CONVERSIONS](https://json.nlohmann.me/api/macros/json_use_implicit_conversions/index.md) +- [JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON](https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/index.md) +- [NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/index.md) +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/index.md) +- [NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE](https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/index.md) +- [NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT_WITH_NAMES, NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE_WITH_NAMES](https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/index.md) +- [NLOHMANN_JSON_NAMESPACE](https://json.nlohmann.me/api/macros/nlohmann_json_namespace/index.md) +- [NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/index.md) +- [NLOHMANN_JSON_NAMESPACE_NO_VERSION](https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/index.md) +- [NLOHMANN_JSON_SERIALIZE_ENUM](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/index.md) +- [NLOHMANN_JSON_SERIALIZE_ENUM_STRICT](https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/index.md) +- [NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH](https://json.nlohmann.me/api/macros/nlohmann_json_version_major/index.md) + +## Community + +- [Community](https://json.nlohmann.me/community/index.md) +- [Code of Conduct](https://json.nlohmann.me/community/code_of_conduct/index.md) +- [Contribution Guidelines](https://json.nlohmann.me/community/contribution_guidelines/index.md) +- [Governance](https://json.nlohmann.me/community/governance/index.md) +- [Quality assurance](https://json.nlohmann.me/community/quality_assurance/index.md) +- [Security Policy](https://json.nlohmann.me/community/security_policy/index.md) + diff --git a/robots.txt b/robots.txt new file mode 100644 index 000000000..f52a66807 --- /dev/null +++ b/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://json.nlohmann.me/sitemap.xml diff --git a/sitemap.xml b/sitemap.xml index 2eb3010af..d83401661 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,1006 +2,1006 @@ https://json.nlohmann.me/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/operator_gtgt/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/operator_literal_json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/operator_literal_json_pointer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/operator_ltlt/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/ordered_json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/ordered_map/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/adl_serializer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/adl_serializer/from_json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/adl_serializer/to_json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/accept/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/array/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/array_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/at/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/back/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/basic_json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/begin/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/binary/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/binary_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/boolean_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/cbegin/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/cbor_tag_handler_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/cend/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/clear/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/contains/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/count/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/crbegin/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/crend/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/default_object_comparator_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/diff/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/dump/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/emplace/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/emplace_back/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/empty/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/end/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/end_pos/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/erase/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/error_handler_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/exception/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/find/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/flatten/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/format_as/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/from_bjdata/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/from_bson/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/from_cbor/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/from_msgpack/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/from_ubjson/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/front/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/get/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/get_allocator/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/get_binary/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/get_ptr/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/get_ref/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/get_to/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/input_format_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/insert/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/invalid_iterator/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_array/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_binary/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_boolean/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_discarded/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_null/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_number/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_number_float/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_number_integer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_number_unsigned/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_object/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_primitive/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_string/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/is_structured/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/items/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/json_base_class_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/json_serializer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/max_size/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/merge_patch/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/meta/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/number_float_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/number_integer_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/number_unsigned_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/object/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/object_comparator_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/object_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator%2B%3D/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator%3D/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator%5B%5D/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_ValueType/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_eq/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_ge/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_gt/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_le/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_lt/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_ne/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_spaceship/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/operator_value_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/other_error/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/out_of_range/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/parse/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/parse_error/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/parse_event_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/parser_callback_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/patch/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/patch_inplace/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/push_back/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/rbegin/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/rend/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/sax_parse/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/size/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/start_pos/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/std_formatter/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/std_hash/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/std_swap/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/string_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/swap/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/to_bjdata/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/to_bson/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/to_cbor/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/to_msgpack/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/to_string/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/to_ubjson/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/type/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/type_error/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/type_name/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/unflatten/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/update/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/value/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/value_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/basic_json/~basic_json/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/byte_container_with_subtype/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/back/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/empty/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/front/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/json_pointer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/operator_eq/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/operator_ne/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/operator_slash/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/operator_slasheq/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/operator_string_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/parent_pointer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/pop_back/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/pop_front/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/push_back/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/push_front/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/string_t/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_pointer/to_string/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/binary/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/boolean/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/end_array/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/end_object/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/key/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/null/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/number_float/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/number_integer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/number_unsigned/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/parse_error/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/start_array/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/start_object/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/json_sax/string/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_assert/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_brace_init_copy_semantics/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_diagnostic_positions/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_diagnostics/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_disable_enum_serialization/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_has_cpp_11/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_has_filesystem/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_has_ranges/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_has_static_rtti/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_has_std_format/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_has_three_way_comparison/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_no_io/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_noexception/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_skip_library_version_check/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_skip_unsupported_compiler_check/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_throw_user/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_use_global_udls/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_use_implicit_conversions/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_define_type_with_names/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_json_namespace/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum_strict/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/api/macros/nlohmann_json_version_major/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/community/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/community/code_of_conduct/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/community/contribution_guidelines/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/community/governance/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/community/quality_assurance/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/community/security_policy/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/arbitrary_types/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/assertions/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/binary_values/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/comments/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/conversions/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/creating_values/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/enum_conversion/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/iterators/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/json_patch/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/json_pointer/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/macros/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/merge_patch/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/modifying_values/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/modules/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/namespace/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/object_order/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/serialization/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/trailing_commas/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/binary_formats/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/binary_formats/bjdata/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/binary_formats/bson/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/binary_formats/cbor/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/binary_formats/messagepack/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/binary_formats/ubjson/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/element_access/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/element_access/checked_access/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/element_access/default_value/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/element_access/unchecked_access/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/parsing/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/parsing/json_lines/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/parsing/parse_exceptions/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/parsing/parser_callbacks/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/parsing/sax_interface/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/types/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/features/types/number_handling/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/architecture/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/customers/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/design_goals/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/exceptions/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/faq/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/license/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/releases/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/home/sponsors/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/integration/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/integration/cmake/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/integration/migration_guide/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/integration/package_managers/ - 2026-07-04 + 2026-07-08 https://json.nlohmann.me/integration/pkg-config/ - 2026-07-04 + 2026-07-08 \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 32df963e602e8d067b03e3adc103dfe5a0d98204..7934056901889d14000894b49714cf685a7349ac 100644 GIT binary patch delta 1774 zcmVex6f>k5jbb9xYxdBxVABKDQ&aFj zd21pm6OaUpLDs%UcLfh^e?1Sh=qPM=%`ysUXGgoG39wRnH4H%YWp+4qo}DJiZ~%d| zloCY*S_#lTnZ$*&z%iLU1!N2KK8-&Om5(iB&GV=DVpD79gc7KNA zuIa9OiiC!Mt{V$NHr&Aoa~K_TYAO^xfEC$+}kr`YB7lP*j z3lJ?%Um3SVvCdNw$r0E?^>0b5UX;x>XuniJfIaMq06j2dgq@!e%FwGI$@kntDa@iZ z7+~($H-I1pZIRnA2avq&KDJRNi+>4fG~hP6bHG6noL94o>XxAtA$ny-G{Pd|;-O6< z@(f({mf)E5o`p=84@k?VpumDRjzDI*7a<`43D}P;97Q=HA&{Ps<9Q6(Dj!c{4Ujy{ zVn`J9B-Yd})(V3pSi=n8zW@66hhG}tXaeHH*S8-U;1Iu)UijPAaRV&;y?+6Sv4xTt z8|be>w@?zgg_1BWltgeOIZVnmz;c^M4d|p2r(|uEJz5~d5``UvCxaX`l93V6^5~ja zA#T|~O`U?_g(R(W;0hK6x;!iLX#L z{kk<6k&dg3F;SSX1mTVxl7Aq(m67uT_Wq-V2Qg&?XwXaozy>fS0C@OPVnA=PBm{K) zRD}9nvO3yuFARoeU@n-G$sOzpe*OX^2kZ?Ph3jmHnLdrpVG?lPQ^)tr9%u1 zuaNvdC`%SwgIvkzZICK(Y>^5=1U!V}ku<!M9pR=eDc_5DfAOUfEf*Xe2JRs%bNE?>w@RR|Qf9s_hfpQxgY%CX6AD*~r)MkSGj(kmK`4T&P} zk*j>nMH@I+ia?!CV^tbC_c1QFvOrVhi!;FgF#B%UjRd-@jQ1P zAESbkJcOBmLE_|@#T{+e6bu!h9miOqEL0zLg3vKVxKU1Mm4D_SzZL7L>q1Uk-8=CN zD%qurbJj=hOM_AQyeBkSYQy$UETOv9ehiW1#i(sZS}eT|U=lSutzB+0xoRe37XYB=|684dnrG5$ZGreD9GO1=;|VB266QxyMJGY5r|0Ze?Ur;|2kH+z_rg`FH4K|h>C+;#umUHOq7|ftNM%5+%Yd{ ziN1wsO51ZzX-ZRUzf`S=V}>;Ts&2^!s~8v6vrfZcfUt}PUBx|GuQY5x3cO zw0IarV7d5=;cPO%YBtP)DIb6m5R&9O70YTRPrw+2;(sx$Z0GLP*WV~8CM^UYw?H-# zq>Wf(9OQj^m3ORhrC;XbLopx_9!~Lt-2ZOxzH%1j6ZPuBG<*H(yCnx@$mv1{dE2XD zi|u;pN{hxwBUW~M@%5~l@&j!MebiRV9w6BpO6Rthr#?c?`a4H{3k22k1z!XSm`3pg zqjK)xOMe(?m=n=lnuwfS~MLaNiEl!;kyaPBMFmXEFF9 z%CSgwLtvgs7YnntXXP2i8kF_0L5XKMoZbRu$>(Mi<9`6zVlb!2PI!$OEI+?fx1&rp zyM?`+((1Duzgt^dE+MAps;k~2+;a}l6r&|wT~`}20u<$ezSox2O0o&n8`Vr0AL$p#x;Tf0N&P6IsgCw delta 1774 zcmVtM~f(RP~2nDd!8mz(_O<8M=lv+b|mU%da}?Bd6> zi+}IaSJuyVm*4EK|F4wDsq$fEN$c2Cv|fyHj3{lLD#?=;$ooHL5Y8%--ojX-u3i_u zXU{#P3RdadP3tOCuSH<5NUJ}p*Y*?f!P^;8`cE*TML={ElmrWtlBkE^>;ifq`WfZw`hH2^Y5(HOn(N6Ai<45cFFdMG>VB#uh~P(f=v%pPffuC z<*kXNOh6JW23h+a-4#5v{q;Q1qNA|gHOnZZogM9#CcsMR)i40nm)YUed3Ks4!vO@= zQc4sNXeB`VWD*z70>@fj!UMMQ0wLU0hOB^)C$jIBbex@i0*nb&{ zyQaJDDH0k2x^658*>DFV%wcrUsi{yb-8H&4kY@A9SaCr*{YSP_u^4D?MrLpkTnL^A zEI_n4eP!Gd#X3(#Bu8Km)xRaJdQmplp#4$>0rs#b0`$O;5q5q?C_}G;B;Runr7(-u zV1T(}-vELbv_)>e96<86``AXAEPp1b(SY0N&H)ESa9+(Ss#}Iqgy@wS(Flu-i-$Ie z$TM)&TY_WKdloWXJ|Hcdf&vTPI0BjJUW9}IBw#==cL;J9ieSz);c!0t>OF|?cv4K<} z_UqPQL^`fA#zbMl5`;T)NPmLtRz}VX*!zzb9>kOppg}VU02{!R0N~+Ei2=REk`U1G zQxWQS$?9msy)YP>fyJ;Gc!25R(wGP=g0h?k%OfYnKXECM+sIN74XK#Up)0zSAQBL_ql?fPYq60&Y+2?=cKF zff00l2f`~PjZ_ZEtMCZMkpmP63b`c?{6`e4>gnD#s?ftq7dH8I?p9O0Q@%HYAF? zN3QZQ7j58RDFSsmja6yn+~=GS;0TaosO-g*&WU&Lzz~Dd9JV3y33=tBWWH< zZV%@Rta0(^Vdvpv(et1Trzfv&b536UowXN;O4vtQmii^s&-8wc$)uWXk*jQy<~W%E zhT2Uj8N}6(?0ehO@~4tJyFIrhEWOKuD7BR4l8NJON`6ihswjvYoqEUw@;Zn6wap+ydD| zkTznCagg`vRo=12m42Cz55<5$csRuma{s%%`^s6APt>ai)9m%D@0J{tA*Tx++c--Ef7@C7km*UU>d~} zjLNx#FMnaAVIt7Tm9q$6qN$$9cQBJQXCqbQpYsc$0fMq~!F@YG4?pfxJIU-Np2gsc zD90kz4S{(kT`bJno|R`5Yf#q11|^>5aC!@rC7+v7jQ;^-i@}^8JK;5Eu>AZ^-HtNZ z>=yQNN~_Ou{BCV+xrCUWtFC&BaL+kFQ;e2$bysc32vC#<`c_*~E6FBQZ&*G}gcP`X z2?v*|wXPSZL_GW2>$qc8Inxb;v}d)x+HIeJDDu)Etq?@|TY7?3zq=XFq&0*350glF Q3LLNg0#U$;={14?0L0~0y#N3J