From 55f10f44a9adf1abc0dbeb3c4ca1b6417faae434 Mon Sep 17 00:00:00 2001 From: <> Date: Wed, 8 Mar 2023 12:43:29 +0000 Subject: [PATCH] Deployed fe4b663 with MkDocs version: 1.4.2 --- .nojekyll | 0 404.html | 1 + api/adl_serializer/from_json/index.html | 104 + api/adl_serializer/index.html | 15 + api/adl_serializer/to_json/index.html | 38 + api/basic_json/accept/index.html | 37 + api/basic_json/array/index.html | 25 + api/basic_json/array_t/index.html | 17 + api/basic_json/at/index.html | 508 ++ api/basic_json/back/index.html | 52 + api/basic_json/basic_json/index.html | 462 ++ api/basic_json/begin/index.html | 20 + api/basic_json/binary/index.html | 27 + api/basic_json/binary_t/index.html | 13 + api/basic_json/boolean_t/index.html | 13 + api/basic_json/cbegin/index.html | 19 + api/basic_json/cbor_tag_handler_t/index.html | 38 + api/basic_json/cend/index.html | 22 + api/basic_json/clear/index.html | 44 + api/basic_json/contains/index.html | 104 + api/basic_json/count/index.html | 49 + api/basic_json/crbegin/index.html | 19 + api/basic_json/crend/index.html | 22 + .../default_object_comparator_t/index.html | 17 + api/basic_json/diff/index.html | 66 + api/basic_json/dump/index.html | 108 + api/basic_json/emplace/index.html | 40 + api/basic_json/emplace_back/index.html | 31 + api/basic_json/empty/index.html | 45 + api/basic_json/end/index.html | 23 + api/basic_json/erase/index.html | 151 + api/basic_json/error_handler_t/index.html | 33 + api/basic_json/exception/index.html | 24 + api/basic_json/find/index.html | 58 + api/basic_json/flatten/index.html | 46 + api/basic_json/from_bjdata/index.html | 35 + api/basic_json/from_bson/index.html | 36 + api/basic_json/from_cbor/index.html | 38 + api/basic_json/from_msgpack/index.html | 35 + api/basic_json/from_ubjson/index.html | 35 + api/basic_json/front/index.html | 38 + api/basic_json/get/index.html | 106 + api/basic_json/get_allocator/index.html | 21 + api/basic_json/get_binary/index.html | 21 + api/basic_json/get_ptr/index.html | 29 + api/basic_json/get_ref/index.html | 35 + api/basic_json/get_to/index.html | 78 + api/basic_json/index.html | 81 + api/basic_json/input_format_t/index.html | 126 + api/basic_json/insert/index.html | 119 + api/basic_json/invalid_iterator/index.html | 25 + api/basic_json/is_array/index.html | 41 + api/basic_json/is_binary/index.html | 41 + api/basic_json/is_boolean/index.html | 41 + api/basic_json/is_discarded/index.html | 43 + api/basic_json/is_null/index.html | 41 + api/basic_json/is_number/index.html | 45 + api/basic_json/is_number_float/index.html | 41 + api/basic_json/is_number_integer/index.html | 41 + api/basic_json/is_number_unsigned/index.html | 41 + api/basic_json/is_object/index.html | 41 + api/basic_json/is_primitive/index.html | 45 + api/basic_json/is_string/index.html | 41 + api/basic_json/is_structured/index.html | 45 + api/basic_json/items/index.html | 50 + api/basic_json/json_base_class_t/index.html | 94 + api/basic_json/json_serializer/index.html | 57 + api/basic_json/max_size/index.html | 34 + api/basic_json/merge_patch/index.html | 67 + api/basic_json/meta/index.html | 30 + api/basic_json/number_float_t/index.html | 13 + api/basic_json/number_integer_t/index.html | 13 + api/basic_json/number_unsigned_t/index.html | 13 + api/basic_json/object/index.html | 34 + api/basic_json/object_comparator_t/index.html | 17 + api/basic_json/object_t/index.html | 31 + api/basic_json/operator+=/index.html | 99 + api/basic_json/operator=/index.html | 27 + api/basic_json/operator[]/index.html | 286 + api/basic_json/operator_ValueType/index.html | 79 + api/basic_json/operator_eq/index.html | 118 + api/basic_json/operator_ge/index.html | 37 + api/basic_json/operator_gt/index.html | 37 + api/basic_json/operator_gtgt/index.html | 15 + api/basic_json/operator_le/index.html | 37 + .../operator_literal_json/index.html | 15 + .../operator_literal_json_pointer/index.html | 15 + api/basic_json/operator_lt/index.html | 37 + api/basic_json/operator_ltlt/index.html | 15 + api/basic_json/operator_ne/index.html | 72 + api/basic_json/operator_spaceship/index.html | 98 + api/basic_json/operator_value_t/index.html | 48 + api/basic_json/other_error/index.html | 34 + api/basic_json/out_of_range/index.html | 24 + api/basic_json/parse/index.html | 336 + api/basic_json/parse_error/index.html | 25 + api/basic_json/parse_event_t/index.html | 9 + api/basic_json/parser_callback_t/index.html | 87 + api/basic_json/patch/index.html | 46 + api/basic_json/patch_inplace/index.html | 50 + api/basic_json/push_back/index.html | 99 + api/basic_json/rbegin/index.html | 20 + api/basic_json/rend/index.html | 23 + api/basic_json/sax_parse/index.html | 184 + api/basic_json/size/index.html | 40 + api/basic_json/std_hash/index.html | 31 + api/basic_json/std_swap/index.html | 29 + api/basic_json/string_t/index.html | 13 + api/basic_json/swap/index.html | 129 + api/basic_json/to_bjdata/index.html | 79 + api/basic_json/to_bson/index.html | 30 + api/basic_json/to_cbor/index.html | 30 + api/basic_json/to_msgpack/index.html | 30 + api/basic_json/to_string/index.html | 31 + api/basic_json/to_ubjson/index.html | 79 + api/basic_json/type/index.html | 38 + api/basic_json/type_error/index.html | 24 + api/basic_json/type_name/index.html | 37 + api/basic_json/unflatten/index.html | 46 + api/basic_json/update/index.html | 113 + api/basic_json/value/index.html | 121 + api/basic_json/value_t/index.html | 49 + api/basic_json/~basic_json/index.html | 2 + .../byte_container_with_subtype/index.html | 37 + .../clear_subtype/index.html | 25 + .../has_subtype/index.html | 23 + api/byte_container_with_subtype/index.html | 3 + .../set_subtype/index.html | 26 + .../subtype/index.html | 26 + api/json/index.html | 68 + api/json_pointer/back/index.html | 19 + api/json_pointer/empty/index.html | 26 + api/json_pointer/index.html | 3 + api/json_pointer/json_pointer/index.html | 52 + api/json_pointer/operator_eq/index.html | 85 + api/json_pointer/operator_ne/index.html | 75 + api/json_pointer/operator_slash/index.html | 31 + api/json_pointer/operator_slasheq/index.html | 36 + api/json_pointer/operator_string/index.html | 15 + api/json_pointer/operator_string_t/index.html | 27 + api/json_pointer/parent_pointer/index.html | 23 + api/json_pointer/pop_back/index.html | 27 + api/json_pointer/push_back/index.html | 29 + api/json_pointer/string_t/index.html | 17 + api/json_pointer/to_string/index.html | 49 + api/json_sax/binary/index.html | 119 + api/json_sax/boolean/index.html | 170 + api/json_sax/end_array/index.html | 170 + api/json_sax/end_object/index.html | 170 + api/json_sax/index.html | 3 + api/json_sax/key/index.html | 170 + api/json_sax/null/index.html | 170 + api/json_sax/number_float/index.html | 170 + api/json_sax/number_integer/index.html | 170 + api/json_sax/number_unsigned/index.html | 170 + api/json_sax/parse_error/index.html | 172 + api/json_sax/start_array/index.html | 170 + api/json_sax/start_object/index.html | 170 + api/json_sax/string/index.html | 170 + api/macros/index.html | 1 + api/macros/json_assert/index.html | 27 + api/macros/json_diagnostics/index.html | 47 + .../index.html | 92 + api/macros/json_has_cpp_11/index.html | 9 + api/macros/json_has_filesystem/index.html | 7 + api/macros/json_has_ranges/index.html | 6 + .../json_has_three_way_comparison/index.html | 6 + api/macros/json_no_io/index.html | 7 + api/macros/json_noexception/index.html | 7 + .../index.html | 4 + .../index.html | 7 + api/macros/json_throw_user/index.html | 24 + api/macros/json_use_global_udls/index.html | 32 + .../json_use_implicit_conversions/index.html | 7 + .../index.html | 7 + .../nlohmann_define_type_intrusive/index.html | 214 + .../index.html | 196 + api/macros/nlohmann_json_namespace/index.html | 17 + .../nlohmann_json_namespace_begin/index.html | 43 + .../index.html | 17 + .../nlohmann_json_serialize_enum/index.html | 104 + .../nlohmann_json_version_major/index.html | 17 + api/operator_gtgt/index.html | 41 + api/operator_literal_json/index.html | 24 + api/operator_literal_json_pointer/index.html | 22 + api/operator_ltlt/index.html | 60 + api/ordered_json/index.html | 21 + api/ordered_map/index.html | 54 + assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.5a2dcb6a.min.js | 29 + assets/javascripts/bundle.5a2dcb6a.min.js.map | 8 + .../javascripts/extra/bundle.5f09fbc3.min.js | 18 + .../extra/bundle.5f09fbc3.min.js.map | 8 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.16e2a7d4.min.js | 48 + .../workers/search.16e2a7d4.min.js.map | 8 + assets/stylesheets/extra.0d2c79a8.min.css | 1 + assets/stylesheets/extra.0d2c79a8.min.css.map | 1 + assets/stylesheets/main.975780f9.min.css | 1 + assets/stylesheets/main.975780f9.min.css.map | 1 + assets/stylesheets/palette.2505c338.min.css | 1 + .../stylesheets/palette.2505c338.min.css.map | 1 + css/custom.css | 4 + examples/README.cpp | 39 + examples/README.output | 27 + examples/accept__string.cpp | 26 + examples/accept__string.output | 1 + examples/array.cpp | 19 + examples/array.output | 4 + examples/array_t.cpp | 10 + examples/array_t.output | 1 + examples/at__json_pointer.cpp | 104 + examples/at__json_pointer.output | 12 + examples/at__json_pointer_const.cpp | 80 + examples/at__json_pointer_const.output | 9 + examples/at__keytype.c++17.cpp | 50 + examples/at__keytype.c++17.output | 4 + examples/at__keytype_const.c++17.cpp | 44 + examples/at__keytype_const.c++17.output | 3 + examples/at__object_t_key_type.cpp | 48 + examples/at__object_t_key_type.output | 4 + examples/at__object_t_key_type_const.cpp | 42 + examples/at__object_t_key_type_const.output | 3 + examples/at__size_type.cpp | 43 + examples/at__size_type.output | 4 + examples/at__size_type_const.cpp | 37 + examples/at__size_type_const.output | 3 + examples/back.cpp | 38 + examples/back.output | 7 + examples/basic_json__CompatibleType.cpp | 218 + examples/basic_json__CompatibleType.output | 39 + examples/basic_json__InputIt_InputIt.cpp | 32 + examples/basic_json__InputIt_InputIt.output | 4 + examples/basic_json__basic_json.cpp | 17 + examples/basic_json__basic_json.output | 2 + examples/basic_json__copyassignment.cpp | 18 + examples/basic_json__copyassignment.output | 2 + examples/basic_json__list_init_t.cpp | 21 + examples/basic_json__list_init_t.output | 5 + examples/basic_json__moveconstructor.cpp | 17 + examples/basic_json__moveconstructor.output | 2 + examples/basic_json__nullptr_t.cpp | 16 + examples/basic_json__nullptr_t.output | 2 + examples/basic_json__size_type_basic_json.cpp | 18 + .../basic_json__size_type_basic_json.output | 3 + examples/basic_json__value_t.cpp | 25 + examples/basic_json__value_t.output | 7 + examples/begin.cpp | 16 + examples/begin.output | 1 + examples/binary.cpp | 16 + examples/binary.output | 1 + examples/binary_t.cpp | 10 + examples/binary_t.output | 1 + examples/boolean_t.cpp | 10 + examples/boolean_t.output | 1 + ...h_subtype__byte_container_with_subtype.cpp | 23 + ...ubtype__byte_container_with_subtype.output | 3 + ..._container_with_subtype__clear_subtype.cpp | 21 + ...ntainer_with_subtype__clear_subtype.output | 2 + ...te_container_with_subtype__has_subtype.cpp | 19 + ...container_with_subtype__has_subtype.output | 2 + ...te_container_with_subtype__set_subtype.cpp | 22 + ...container_with_subtype__set_subtype.output | 2 + .../byte_container_with_subtype__subtype.cpp | 22 + ...yte_container_with_subtype__subtype.output | 2 + examples/cbegin.cpp | 16 + examples/cbegin.output | 1 + examples/cbor_tag_handler_t.cpp | 28 + examples/cbor_tag_handler_t.output | 3 + examples/cend.cpp | 19 + examples/cend.output | 1 + examples/clear.cpp | 34 + examples/clear.output | 7 + examples/contains__json_pointer.cpp | 43 + examples/contains__json_pointer.output | 7 + examples/contains__keytype.c++17.cpp | 20 + examples/contains__keytype.c++17.output | 3 + examples/contains__object_t_key_type.cpp | 18 + examples/contains__object_t_key_type.output | 3 + examples/count__keytype.c++17.cpp | 20 + examples/count__keytype.c++17.output | 2 + examples/count__object_t_key_type.cpp | 18 + examples/count__object_t_key_type.output | 2 + examples/crbegin.cpp | 16 + examples/crbegin.output | 1 + examples/crend.cpp | 19 + examples/crend.output | 1 + examples/default_object_comparator_t.cpp | 11 + examples/default_object_comparator_t.output | 2 + examples/diagnostics_extended.cpp | 22 + examples/diagnostics_extended.output | 1 + examples/diagnostics_standard.cpp | 20 + examples/diagnostics_standard.output | 1 + examples/diff.cpp | 37 + examples/diff.output | 25 + examples/dump.cpp | 48 + examples/dump.output | 55 + examples/emplace.cpp | 31 + examples/emplace.output | 6 + examples/emplace_back.cpp | 24 + examples/emplace_back.output | 4 + examples/empty.cpp | 30 + examples/empty.output | 9 + examples/end.cpp | 19 + examples/end.output | 1 + examples/erase__IteratorType.cpp | 31 + examples/erase__IteratorType.output | 6 + examples/erase__IteratorType_IteratorType.cpp | 31 + .../erase__IteratorType_IteratorType.output | 6 + examples/erase__keytype.c++17.cpp | 20 + examples/erase__keytype.c++17.output | 2 + examples/erase__object_t_key_type.cpp | 18 + examples/erase__object_t_key_type.output | 2 + examples/erase__size_type.cpp | 16 + examples/erase__size_type.output | 1 + examples/error_handler_t.cpp | 24 + examples/error_handler_t.output | 3 + examples/exception.cpp | 20 + examples/exception.output | 2 + examples/find__keytype.c++17.cpp | 22 + examples/find__keytype.c++17.output | 3 + examples/find__object_t_key_type.cpp | 20 + examples/find__object_t_key_type.output | 3 + examples/flatten.cpp | 32 + examples/flatten.output | 12 + examples/from_bjdata.cpp | 20 + examples/from_bjdata.output | 4 + examples/from_bson.cpp | 21 + examples/from_bson.output | 4 + examples/from_cbor.cpp | 20 + examples/from_cbor.output | 4 + examples/from_json__default_constructible.cpp | 37 + .../from_json__default_constructible.output | 1 + .../from_json__non_default_constructible.cpp | 53 + ...rom_json__non_default_constructible.output | 1 + examples/from_msgpack.cpp | 20 + examples/from_msgpack.output | 4 + examples/from_ubjson.cpp | 20 + examples/from_ubjson.output | 4 + examples/front.cpp | 29 + examples/front.output | 6 + examples/get__PointerType.cpp | 21 + examples/get__PointerType.output | 2 + examples/get__ValueType_const.cpp | 50 + examples/get__ValueType_const.output | 11 + examples/get_allocator.cpp | 18 + examples/get_allocator.output | 1 + examples/get_binary.cpp | 16 + examples/get_binary.output | 1 + examples/get_ptr.cpp | 21 + examples/get_ptr.output | 2 + examples/get_ref.cpp | 27 + examples/get_ref.output | 2 + examples/get_to.cpp | 60 + examples/get_to.output | 11 + examples/insert.cpp | 17 + examples/insert.output | 2 + examples/insert__count.cpp | 17 + examples/insert__count.output | 2 + examples/insert__ilist.cpp | 17 + examples/insert__ilist.output | 2 + examples/insert__range.cpp | 20 + examples/insert__range.output | 2 + examples/insert__range_object.cpp | 21 + examples/insert__range_object.output | 3 + examples/invalid_iterator.cpp | 21 + examples/invalid_iterator.output | 2 + examples/is_array.cpp | 30 + examples/is_array.output | 9 + examples/is_binary.cpp | 30 + examples/is_binary.output | 9 + examples/is_boolean.cpp | 30 + examples/is_boolean.output | 9 + examples/is_discarded.cpp | 30 + examples/is_discarded.output | 9 + examples/is_null.cpp | 30 + examples/is_null.output | 9 + examples/is_number.cpp | 30 + examples/is_number.output | 9 + examples/is_number_float.cpp | 30 + examples/is_number_float.output | 9 + examples/is_number_integer.cpp | 30 + examples/is_number_integer.output | 9 + examples/is_number_unsigned.cpp | 30 + examples/is_number_unsigned.output | 9 + examples/is_object.cpp | 30 + examples/is_object.output | 9 + examples/is_primitive.cpp | 30 + examples/is_primitive.output | 9 + examples/is_string.cpp | 30 + examples/is_string.output | 9 + examples/is_structured.cpp | 30 + examples/is_structured.output | 9 + examples/items.cpp | 23 + examples/items.output | 7 + examples/json_base_class_t.cpp | 88 + examples/json_base_class_t.output | 4 + examples/json_lines.cpp | 22 + examples/json_lines.output | 4 + examples/json_pointer.cpp | 47 + examples/json_pointer.output | 3 + examples/json_pointer__back.cpp | 15 + examples/json_pointer__back.output | 2 + examples/json_pointer__empty.cpp | 20 + examples/json_pointer__empty.output | 4 + examples/json_pointer__operator__equal.cpp | 19 + examples/json_pointer__operator__equal.output | 4 + ...on_pointer__operator__equal_stringtype.cpp | 33 + ...pointer__operator__equal_stringtype.output | 4 + examples/json_pointer__operator__notequal.cpp | 19 + .../json_pointer__operator__notequal.output | 4 + ...pointer__operator__notequal_stringtype.cpp | 32 + ...nter__operator__notequal_stringtype.output | 4 + examples/json_pointer__operator_add.cpp | 23 + examples/json_pointer__operator_add.output | 4 + .../json_pointer__operator_add_binary.cpp | 19 + .../json_pointer__operator_add_binary.output | 3 + examples/json_pointer__operator_string_t.cpp | 19 + .../json_pointer__operator_string_t.output | 2 + examples/json_pointer__parent_pointer.cpp | 18 + examples/json_pointer__parent_pointer.output | 3 + examples/json_pointer__pop_back.cpp | 21 + examples/json_pointer__pop_back.output | 4 + examples/json_pointer__push_back.cpp | 21 + examples/json_pointer__push_back.output | 4 + examples/json_pointer__string_t.cpp | 13 + examples/json_pointer__string_t.output | 2 + examples/json_pointer__to_string.cpp | 34 + examples/json_pointer__to_string.output | 12 + examples/max_size.cpp | 25 + examples/max_size.output | 7 + examples/merge_patch.cpp | 41 + examples/merge_patch.output | 11 + examples/meta.cpp | 11 + examples/meta.output | 17 + ...lohmann_define_type_intrusive_explicit.cpp | 60 + ...mann_define_type_intrusive_explicit.output | 2 + .../nlohmann_define_type_intrusive_macro.cpp | 48 + ...lohmann_define_type_intrusive_macro.output | 2 + ...e_type_intrusive_with_default_explicit.cpp | 55 + ...ype_intrusive_with_default_explicit.output | 2 + ...fine_type_intrusive_with_default_macro.cpp | 42 + ...e_type_intrusive_with_default_macro.output | 2 + ...ann_define_type_non_intrusive_explicit.cpp | 53 + ..._define_type_non_intrusive_explicit.output | 2 + ...ohmann_define_type_non_intrusive_macro.cpp | 41 + ...ann_define_type_non_intrusive_macro.output | 2 + ...pe_non_intrusive_with_default_explicit.cpp | 53 + ...non_intrusive_with_default_explicit.output | 2 + ..._type_non_intrusive_with_default_macro.cpp | 40 + ...pe_non_intrusive_with_default_macro.output | 2 + examples/nlohmann_json_namespace.cpp | 14 + examples/nlohmann_json_namespace.output | 1 + .../nlohmann_json_namespace_begin.c++17.cpp | 33 + ...nlohmann_json_namespace_begin.c++17.output | 1 + .../nlohmann_json_namespace_no_version.cpp | 13 + .../nlohmann_json_namespace_no_version.output | 1 + examples/nlohmann_json_serialize_enum.cpp | 59 + examples/nlohmann_json_serialize_enum.output | 3 + examples/nlohmann_json_serialize_enum_2.cpp | 33 + .../nlohmann_json_serialize_enum_2.output | 3 + examples/nlohmann_json_version.cpp | 12 + examples/nlohmann_json_version.output | 1 + examples/number_float_t.cpp | 10 + examples/number_float_t.output | 1 + examples/number_integer_t.cpp | 10 + examples/number_integer_t.output | 1 + examples/number_unsigned_t.cpp | 10 + examples/number_unsigned_t.output | 1 + examples/object.cpp | 28 + examples/object.output | 4 + examples/object_comparator_t.cpp | 11 + examples/object_comparator_t.output | 2 + examples/object_t.cpp | 10 + examples/object_t.output | 1 + examples/operator__ValueType.cpp | 60 + examples/operator__ValueType.output | 12 + examples/operator__equal.cpp | 24 + examples/operator__equal.output | 4 + examples/operator__equal__nullptr_t.cpp | 22 + examples/operator__equal__nullptr_t.output | 5 + examples/operator__equal__specializations.cpp | 16 + .../operator__equal__specializations.output | 2 + examples/operator__greater.cpp | 24 + examples/operator__greater.output | 4 + examples/operator__greaterequal.cpp | 24 + examples/operator__greaterequal.output | 4 + examples/operator__less.cpp | 24 + examples/operator__less.output | 4 + examples/operator__lessequal.cpp | 24 + examples/operator__lessequal.output | 4 + examples/operator__notequal.cpp | 24 + examples/operator__notequal.output | 4 + examples/operator__notequal__nullptr_t.cpp | 22 + examples/operator__notequal__nullptr_t.output | 5 + examples/operator__value_t.cpp | 38 + examples/operator__value_t.output | 8 + examples/operator_array__json_pointer.cpp | 49 + examples/operator_array__json_pointer.output | 8 + .../operator_array__json_pointer_const.cpp | 25 + .../operator_array__json_pointer_const.output | 4 + examples/operator_array__keytype.c++17.cpp | 34 + examples/operator_array__keytype.c++17.output | 19 + .../operator_array__keytype_const.c++17.cpp | 18 + ...operator_array__keytype_const.c++17.output | 1 + .../operator_array__object_t_key_type.cpp | 32 + .../operator_array__object_t_key_type.output | 19 + ...perator_array__object_t_key_type_const.cpp | 16 + ...ator_array__object_t_key_type_const.output | 1 + examples/operator_array__size_type.cpp | 25 + examples/operator_array__size_type.output | 3 + examples/operator_array__size_type_const.cpp | 13 + .../operator_array__size_type_const.output | 1 + examples/operator_deserialize.cpp | 26 + examples/operator_deserialize.output | 13 + examples/operator_literal_json.cpp | 13 + examples/operator_literal_json.output | 4 + examples/operator_literal_json_pointer.cpp | 14 + examples/operator_literal_json_pointer.output | 1 + examples/operator_ltlt__basic_json.cpp | 21 + examples/operator_ltlt__basic_json.output | 22 + examples/operator_ltlt__json_pointer.cpp | 13 + examples/operator_ltlt__json_pointer.output | 1 + ...rator_spaceship__const_reference.c++20.cpp | 41 + ...or_spaceship__const_reference.c++20.output | 4 + .../operator_spaceship__scalartype.c++20.cpp | 41 + ...perator_spaceship__scalartype.c++20.output | 4 + examples/ordered_json.cpp | 14 + examples/ordered_json.output | 5 + examples/ordered_map.cpp | 43 + examples/ordered_map.output | 4 + examples/other_error.cpp | 30 + examples/other_error.output | 2 + examples/out_of_range.cpp | 20 + examples/out_of_range.output | 2 + examples/parse__allow_exceptions.cpp | 36 + examples/parse__allow_exceptions.output | 2 + examples/parse__array__parser_callback_t.cpp | 30 + .../parse__array__parser_callback_t.output | 20 + ...contiguouscontainer__parser_callback_t.cpp | 15 + ...tiguouscontainer__parser_callback_t.output | 6 + .../parse__istream__parser_callback_t.cpp | 58 + .../parse__istream__parser_callback_t.output | 34 + examples/parse__iterator_pair.cpp | 15 + examples/parse__iterator_pair.output | 6 + examples/parse__pointers.cpp | 15 + examples/parse__pointers.output | 6 + examples/parse__string__parser_callback_t.cpp | 49 + .../parse__string__parser_callback_t.output | 34 + examples/parse_error.cpp | 20 + examples/parse_error.output | 3 + examples/patch.cpp | 33 + examples/patch.output | 11 + examples/patch_inplace.cpp | 35 + examples/patch_inplace.output | 13 + examples/push_back.cpp | 25 + examples/push_back.output | 4 + examples/push_back__initializer_list.cpp | 27 + examples/push_back__initializer_list.output | 4 + examples/push_back__object_t__value.cpp | 25 + examples/push_back__object_t__value.output | 4 + examples/rbegin.cpp | 16 + examples/rbegin.output | 1 + examples/rend.cpp | 19 + examples/rend.output | 1 + examples/sax_parse.cpp | 131 + examples/sax_parse.output | 37 + examples/sax_parse__binary.cpp | 114 + examples/sax_parse__binary.output | 3 + examples/size.cpp | 29 + examples/size.output | 9 + examples/std_hash.cpp | 19 + examples/std_hash.output | 8 + examples/std_swap.cpp | 19 + examples/std_swap.output | 2 + examples/string_t.cpp | 10 + examples/string_t.output | 1 + examples/swap__array_t.cpp | 20 + examples/swap__array_t.output | 2 + examples/swap__binary_t.cpp | 20 + examples/swap__binary_t.output | 2 + examples/swap__object_t.cpp | 20 + examples/swap__object_t.output | 2 + examples/swap__reference.cpp | 18 + examples/swap__reference.output | 2 + examples/swap__string_t.cpp | 20 + examples/swap__string_t.output | 2 + examples/to_bjdata.cpp | 64 + examples/to_bjdata.output | 4 + examples/to_bson.cpp | 22 + examples/to_bson.output | 1 + examples/to_cbor.cpp | 22 + examples/to_cbor.output | 1 + examples/to_json.cpp | 32 + examples/to_json.output | 1 + examples/to_msgpack.cpp | 22 + examples/to_msgpack.output | 1 + examples/to_string.cpp | 20 + examples/to_string.output | 3 + examples/to_ubjson.cpp | 64 + examples/to_ubjson.output | 4 + examples/type.cpp | 28 + examples/type.output | 8 + examples/type_error.cpp | 20 + examples/type_error.output | 2 + examples/type_name.cpp | 27 + examples/type_name.output | 8 + examples/unflatten.cpp | 26 + examples/unflatten.output | 18 + examples/update.cpp | 24 + examples/update.output | 17 + examples/update__range.cpp | 24 + examples/update__range.output | 17 + examples/value__json_ptr.cpp | 31 + examples/value__json_ptr.output | 1 + examples/value__keytype.c++17.cpp | 32 + examples/value__keytype.c++17.output | 1 + examples/value__object_t_key_type.cpp | 30 + examples/value__object_t_key_type.output | 1 + features/arbitrary_types/index.html | 162 + features/assertions/index.html | 41 + features/binary_formats/bjdata/index.html | 98 + features/binary_formats/bson/index.html | 49 + features/binary_formats/cbor/index.html | 48 + features/binary_formats/index.html | 1 + .../binary_formats/messagepack/index.html | 48 + features/binary_formats/ubjson/index.html | 93 + features/binary_values/index.html | 146 + features/comments/index.html | 53 + .../element_access/checked_access/index.html | 15 + .../element_access/default_value/index.html | 5 + features/element_access/index.html | 1 + .../unchecked_access/index.html | 22 + features/enum_conversion/index.html | 27 + features/iterators/index.html | 56 + features/json_patch/index.html | 108 + features/json_pointer/index.html | 48 + features/macros/index.html | 1 + features/merge_patch/index.html | 53 + features/namespace/index.html | 4 + features/object_order/index.html | 60 + features/parsing/index.html | 1 + features/parsing/json_lines/index.html | 36 + features/parsing/parse_exceptions/index.html | 66 + features/parsing/parser_callbacks/index.html | 94 + features/parsing/sax_interface/index.html | 29 + features/types/index.html | 39 + features/types/number_handling/index.html | 57 + home/code_of_conduct/index.html | 1 + home/design_goals/index.html | 1 + home/exceptions/index.html | 259 + home/faq/index.html | 29 + home/license/index.html | 1 + home/releases/index.html | 10 + home/sponsors/index.html | 1 + images/callback_events.png | Bin 0 -> 46039 bytes images/json.gif | Bin 0 -> 1644689 bytes images/json_syntax_number.png | Bin 0 -> 37014 bytes images/range-begin-end.svg | 435 ++ images/range-rbegin-rend.svg | 1232 +++ index.html | 1 + integration/cmake/index.html | 49 + integration/conan/CMakeLists.txt | 9 + integration/conan/Conanfile.txt | 5 + integration/conan/example.cpp | 9 + integration/example.cpp | 10 + integration/index.html | 5 + integration/migration_guide/index.html | 57 + integration/package_managers/index.html | 96 + integration/pkg-config/index.html | 3 + integration/vcpkg/CMakeLists.txt | 7 + integration/vcpkg/example.cpp | 9 + search/search_index.json | 1 + sitemap.xml | 1118 +++ sitemap.xml.gz | Bin 0 -> 1642 bytes 702 files changed, 30461 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 api/adl_serializer/from_json/index.html create mode 100644 api/adl_serializer/index.html create mode 100644 api/adl_serializer/to_json/index.html create mode 100644 api/basic_json/accept/index.html create mode 100644 api/basic_json/array/index.html create mode 100644 api/basic_json/array_t/index.html create mode 100644 api/basic_json/at/index.html create mode 100644 api/basic_json/back/index.html create mode 100644 api/basic_json/basic_json/index.html create mode 100644 api/basic_json/begin/index.html create mode 100644 api/basic_json/binary/index.html create mode 100644 api/basic_json/binary_t/index.html create mode 100644 api/basic_json/boolean_t/index.html create mode 100644 api/basic_json/cbegin/index.html create mode 100644 api/basic_json/cbor_tag_handler_t/index.html create mode 100644 api/basic_json/cend/index.html create mode 100644 api/basic_json/clear/index.html create mode 100644 api/basic_json/contains/index.html create mode 100644 api/basic_json/count/index.html create mode 100644 api/basic_json/crbegin/index.html create mode 100644 api/basic_json/crend/index.html create mode 100644 api/basic_json/default_object_comparator_t/index.html create mode 100644 api/basic_json/diff/index.html create mode 100644 api/basic_json/dump/index.html create mode 100644 api/basic_json/emplace/index.html create mode 100644 api/basic_json/emplace_back/index.html create mode 100644 api/basic_json/empty/index.html create mode 100644 api/basic_json/end/index.html create mode 100644 api/basic_json/erase/index.html create mode 100644 api/basic_json/error_handler_t/index.html create mode 100644 api/basic_json/exception/index.html create mode 100644 api/basic_json/find/index.html create mode 100644 api/basic_json/flatten/index.html create mode 100644 api/basic_json/from_bjdata/index.html create mode 100644 api/basic_json/from_bson/index.html create mode 100644 api/basic_json/from_cbor/index.html create mode 100644 api/basic_json/from_msgpack/index.html create mode 100644 api/basic_json/from_ubjson/index.html create mode 100644 api/basic_json/front/index.html create mode 100644 api/basic_json/get/index.html create mode 100644 api/basic_json/get_allocator/index.html create mode 100644 api/basic_json/get_binary/index.html create mode 100644 api/basic_json/get_ptr/index.html create mode 100644 api/basic_json/get_ref/index.html create mode 100644 api/basic_json/get_to/index.html create mode 100644 api/basic_json/index.html create mode 100644 api/basic_json/input_format_t/index.html create mode 100644 api/basic_json/insert/index.html create mode 100644 api/basic_json/invalid_iterator/index.html create mode 100644 api/basic_json/is_array/index.html create mode 100644 api/basic_json/is_binary/index.html create mode 100644 api/basic_json/is_boolean/index.html create mode 100644 api/basic_json/is_discarded/index.html create mode 100644 api/basic_json/is_null/index.html create mode 100644 api/basic_json/is_number/index.html create mode 100644 api/basic_json/is_number_float/index.html create mode 100644 api/basic_json/is_number_integer/index.html create mode 100644 api/basic_json/is_number_unsigned/index.html create mode 100644 api/basic_json/is_object/index.html create mode 100644 api/basic_json/is_primitive/index.html create mode 100644 api/basic_json/is_string/index.html create mode 100644 api/basic_json/is_structured/index.html create mode 100644 api/basic_json/items/index.html create mode 100644 api/basic_json/json_base_class_t/index.html create mode 100644 api/basic_json/json_serializer/index.html create mode 100644 api/basic_json/max_size/index.html create mode 100644 api/basic_json/merge_patch/index.html create mode 100644 api/basic_json/meta/index.html create mode 100644 api/basic_json/number_float_t/index.html create mode 100644 api/basic_json/number_integer_t/index.html create mode 100644 api/basic_json/number_unsigned_t/index.html create mode 100644 api/basic_json/object/index.html create mode 100644 api/basic_json/object_comparator_t/index.html create mode 100644 api/basic_json/object_t/index.html create mode 100644 api/basic_json/operator+=/index.html create mode 100644 api/basic_json/operator=/index.html create mode 100644 api/basic_json/operator[]/index.html create mode 100644 api/basic_json/operator_ValueType/index.html create mode 100644 api/basic_json/operator_eq/index.html create mode 100644 api/basic_json/operator_ge/index.html create mode 100644 api/basic_json/operator_gt/index.html create mode 100644 api/basic_json/operator_gtgt/index.html create mode 100644 api/basic_json/operator_le/index.html create mode 100644 api/basic_json/operator_literal_json/index.html create mode 100644 api/basic_json/operator_literal_json_pointer/index.html create mode 100644 api/basic_json/operator_lt/index.html create mode 100644 api/basic_json/operator_ltlt/index.html create mode 100644 api/basic_json/operator_ne/index.html create mode 100644 api/basic_json/operator_spaceship/index.html create mode 100644 api/basic_json/operator_value_t/index.html create mode 100644 api/basic_json/other_error/index.html create mode 100644 api/basic_json/out_of_range/index.html create mode 100644 api/basic_json/parse/index.html create mode 100644 api/basic_json/parse_error/index.html create mode 100644 api/basic_json/parse_event_t/index.html create mode 100644 api/basic_json/parser_callback_t/index.html create mode 100644 api/basic_json/patch/index.html create mode 100644 api/basic_json/patch_inplace/index.html create mode 100644 api/basic_json/push_back/index.html create mode 100644 api/basic_json/rbegin/index.html create mode 100644 api/basic_json/rend/index.html create mode 100644 api/basic_json/sax_parse/index.html create mode 100644 api/basic_json/size/index.html create mode 100644 api/basic_json/std_hash/index.html create mode 100644 api/basic_json/std_swap/index.html create mode 100644 api/basic_json/string_t/index.html create mode 100644 api/basic_json/swap/index.html create mode 100644 api/basic_json/to_bjdata/index.html create mode 100644 api/basic_json/to_bson/index.html create mode 100644 api/basic_json/to_cbor/index.html create mode 100644 api/basic_json/to_msgpack/index.html create mode 100644 api/basic_json/to_string/index.html create mode 100644 api/basic_json/to_ubjson/index.html create mode 100644 api/basic_json/type/index.html create mode 100644 api/basic_json/type_error/index.html create mode 100644 api/basic_json/type_name/index.html create mode 100644 api/basic_json/unflatten/index.html create mode 100644 api/basic_json/update/index.html create mode 100644 api/basic_json/value/index.html create mode 100644 api/basic_json/value_t/index.html create mode 100644 api/basic_json/~basic_json/index.html create mode 100644 api/byte_container_with_subtype/byte_container_with_subtype/index.html create mode 100644 api/byte_container_with_subtype/clear_subtype/index.html create mode 100644 api/byte_container_with_subtype/has_subtype/index.html create mode 100644 api/byte_container_with_subtype/index.html create mode 100644 api/byte_container_with_subtype/set_subtype/index.html create mode 100644 api/byte_container_with_subtype/subtype/index.html create mode 100644 api/json/index.html create mode 100644 api/json_pointer/back/index.html create mode 100644 api/json_pointer/empty/index.html create mode 100644 api/json_pointer/index.html create mode 100644 api/json_pointer/json_pointer/index.html create mode 100644 api/json_pointer/operator_eq/index.html create mode 100644 api/json_pointer/operator_ne/index.html create mode 100644 api/json_pointer/operator_slash/index.html create mode 100644 api/json_pointer/operator_slasheq/index.html create mode 100644 api/json_pointer/operator_string/index.html create mode 100644 api/json_pointer/operator_string_t/index.html create mode 100644 api/json_pointer/parent_pointer/index.html create mode 100644 api/json_pointer/pop_back/index.html create mode 100644 api/json_pointer/push_back/index.html create mode 100644 api/json_pointer/string_t/index.html create mode 100644 api/json_pointer/to_string/index.html create mode 100644 api/json_sax/binary/index.html create mode 100644 api/json_sax/boolean/index.html create mode 100644 api/json_sax/end_array/index.html create mode 100644 api/json_sax/end_object/index.html create mode 100644 api/json_sax/index.html create mode 100644 api/json_sax/key/index.html create mode 100644 api/json_sax/null/index.html create mode 100644 api/json_sax/number_float/index.html create mode 100644 api/json_sax/number_integer/index.html create mode 100644 api/json_sax/number_unsigned/index.html create mode 100644 api/json_sax/parse_error/index.html create mode 100644 api/json_sax/start_array/index.html create mode 100644 api/json_sax/start_object/index.html create mode 100644 api/json_sax/string/index.html create mode 100644 api/macros/index.html create mode 100644 api/macros/json_assert/index.html create mode 100644 api/macros/json_diagnostics/index.html create mode 100644 api/macros/json_disable_enum_serialization/index.html create mode 100644 api/macros/json_has_cpp_11/index.html create mode 100644 api/macros/json_has_filesystem/index.html create mode 100644 api/macros/json_has_ranges/index.html create mode 100644 api/macros/json_has_three_way_comparison/index.html create mode 100644 api/macros/json_no_io/index.html create mode 100644 api/macros/json_noexception/index.html create mode 100644 api/macros/json_skip_library_version_check/index.html create mode 100644 api/macros/json_skip_unsupported_compiler_check/index.html create mode 100644 api/macros/json_throw_user/index.html create mode 100644 api/macros/json_use_global_udls/index.html create mode 100644 api/macros/json_use_implicit_conversions/index.html create mode 100644 api/macros/json_use_legacy_discarded_value_comparison/index.html create mode 100644 api/macros/nlohmann_define_type_intrusive/index.html create mode 100644 api/macros/nlohmann_define_type_non_intrusive/index.html create mode 100644 api/macros/nlohmann_json_namespace/index.html create mode 100644 api/macros/nlohmann_json_namespace_begin/index.html create mode 100644 api/macros/nlohmann_json_namespace_no_version/index.html create mode 100644 api/macros/nlohmann_json_serialize_enum/index.html create mode 100644 api/macros/nlohmann_json_version_major/index.html create mode 100644 api/operator_gtgt/index.html create mode 100644 api/operator_literal_json/index.html create mode 100644 api/operator_literal_json_pointer/index.html create mode 100644 api/operator_ltlt/index.html create mode 100644 api/ordered_json/index.html create mode 100644 api/ordered_map/index.html create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.5a2dcb6a.min.js create mode 100644 assets/javascripts/bundle.5a2dcb6a.min.js.map create mode 100644 assets/javascripts/extra/bundle.5f09fbc3.min.js create mode 100644 assets/javascripts/extra/bundle.5f09fbc3.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.16e2a7d4.min.js create mode 100644 assets/javascripts/workers/search.16e2a7d4.min.js.map create mode 100644 assets/stylesheets/extra.0d2c79a8.min.css create mode 100644 assets/stylesheets/extra.0d2c79a8.min.css.map create mode 100644 assets/stylesheets/main.975780f9.min.css create mode 100644 assets/stylesheets/main.975780f9.min.css.map create mode 100644 assets/stylesheets/palette.2505c338.min.css create mode 100644 assets/stylesheets/palette.2505c338.min.css.map create mode 100644 css/custom.css create mode 100644 examples/README.cpp create mode 100644 examples/README.output create mode 100644 examples/accept__string.cpp create mode 100644 examples/accept__string.output create mode 100644 examples/array.cpp create mode 100644 examples/array.output create mode 100644 examples/array_t.cpp create mode 100644 examples/array_t.output create mode 100644 examples/at__json_pointer.cpp create mode 100644 examples/at__json_pointer.output create mode 100644 examples/at__json_pointer_const.cpp create mode 100644 examples/at__json_pointer_const.output create mode 100644 examples/at__keytype.c++17.cpp create mode 100644 examples/at__keytype.c++17.output create mode 100644 examples/at__keytype_const.c++17.cpp create mode 100644 examples/at__keytype_const.c++17.output create mode 100644 examples/at__object_t_key_type.cpp create mode 100644 examples/at__object_t_key_type.output create mode 100644 examples/at__object_t_key_type_const.cpp create mode 100644 examples/at__object_t_key_type_const.output create mode 100644 examples/at__size_type.cpp create mode 100644 examples/at__size_type.output create mode 100644 examples/at__size_type_const.cpp create mode 100644 examples/at__size_type_const.output create mode 100644 examples/back.cpp create mode 100644 examples/back.output create mode 100644 examples/basic_json__CompatibleType.cpp create mode 100644 examples/basic_json__CompatibleType.output create mode 100644 examples/basic_json__InputIt_InputIt.cpp create mode 100644 examples/basic_json__InputIt_InputIt.output create mode 100644 examples/basic_json__basic_json.cpp create mode 100644 examples/basic_json__basic_json.output create mode 100644 examples/basic_json__copyassignment.cpp create mode 100644 examples/basic_json__copyassignment.output create mode 100644 examples/basic_json__list_init_t.cpp create mode 100644 examples/basic_json__list_init_t.output create mode 100644 examples/basic_json__moveconstructor.cpp create mode 100644 examples/basic_json__moveconstructor.output create mode 100644 examples/basic_json__nullptr_t.cpp create mode 100644 examples/basic_json__nullptr_t.output create mode 100644 examples/basic_json__size_type_basic_json.cpp create mode 100644 examples/basic_json__size_type_basic_json.output create mode 100644 examples/basic_json__value_t.cpp create mode 100644 examples/basic_json__value_t.output create mode 100644 examples/begin.cpp create mode 100644 examples/begin.output create mode 100644 examples/binary.cpp create mode 100644 examples/binary.output create mode 100644 examples/binary_t.cpp create mode 100644 examples/binary_t.output create mode 100644 examples/boolean_t.cpp create mode 100644 examples/boolean_t.output create mode 100644 examples/byte_container_with_subtype__byte_container_with_subtype.cpp create mode 100644 examples/byte_container_with_subtype__byte_container_with_subtype.output create mode 100644 examples/byte_container_with_subtype__clear_subtype.cpp create mode 100644 examples/byte_container_with_subtype__clear_subtype.output create mode 100644 examples/byte_container_with_subtype__has_subtype.cpp create mode 100644 examples/byte_container_with_subtype__has_subtype.output create mode 100644 examples/byte_container_with_subtype__set_subtype.cpp create mode 100644 examples/byte_container_with_subtype__set_subtype.output create mode 100644 examples/byte_container_with_subtype__subtype.cpp create mode 100644 examples/byte_container_with_subtype__subtype.output create mode 100644 examples/cbegin.cpp create mode 100644 examples/cbegin.output create mode 100644 examples/cbor_tag_handler_t.cpp create mode 100644 examples/cbor_tag_handler_t.output create mode 100644 examples/cend.cpp create mode 100644 examples/cend.output create mode 100644 examples/clear.cpp create mode 100644 examples/clear.output create mode 100644 examples/contains__json_pointer.cpp create mode 100644 examples/contains__json_pointer.output create mode 100644 examples/contains__keytype.c++17.cpp create mode 100644 examples/contains__keytype.c++17.output create mode 100644 examples/contains__object_t_key_type.cpp create mode 100644 examples/contains__object_t_key_type.output create mode 100644 examples/count__keytype.c++17.cpp create mode 100644 examples/count__keytype.c++17.output create mode 100644 examples/count__object_t_key_type.cpp create mode 100644 examples/count__object_t_key_type.output create mode 100644 examples/crbegin.cpp create mode 100644 examples/crbegin.output create mode 100644 examples/crend.cpp create mode 100644 examples/crend.output create mode 100644 examples/default_object_comparator_t.cpp create mode 100644 examples/default_object_comparator_t.output create mode 100644 examples/diagnostics_extended.cpp create mode 100644 examples/diagnostics_extended.output create mode 100644 examples/diagnostics_standard.cpp create mode 100644 examples/diagnostics_standard.output create mode 100644 examples/diff.cpp create mode 100644 examples/diff.output create mode 100644 examples/dump.cpp create mode 100644 examples/dump.output create mode 100644 examples/emplace.cpp create mode 100644 examples/emplace.output create mode 100644 examples/emplace_back.cpp create mode 100644 examples/emplace_back.output create mode 100644 examples/empty.cpp create mode 100644 examples/empty.output create mode 100644 examples/end.cpp create mode 100644 examples/end.output create mode 100644 examples/erase__IteratorType.cpp create mode 100644 examples/erase__IteratorType.output create mode 100644 examples/erase__IteratorType_IteratorType.cpp create mode 100644 examples/erase__IteratorType_IteratorType.output create mode 100644 examples/erase__keytype.c++17.cpp create mode 100644 examples/erase__keytype.c++17.output create mode 100644 examples/erase__object_t_key_type.cpp create mode 100644 examples/erase__object_t_key_type.output create mode 100644 examples/erase__size_type.cpp create mode 100644 examples/erase__size_type.output create mode 100644 examples/error_handler_t.cpp create mode 100644 examples/error_handler_t.output create mode 100644 examples/exception.cpp create mode 100644 examples/exception.output create mode 100644 examples/find__keytype.c++17.cpp create mode 100644 examples/find__keytype.c++17.output create mode 100644 examples/find__object_t_key_type.cpp create mode 100644 examples/find__object_t_key_type.output create mode 100644 examples/flatten.cpp create mode 100644 examples/flatten.output create mode 100644 examples/from_bjdata.cpp create mode 100644 examples/from_bjdata.output create mode 100644 examples/from_bson.cpp create mode 100644 examples/from_bson.output create mode 100644 examples/from_cbor.cpp create mode 100644 examples/from_cbor.output create mode 100644 examples/from_json__default_constructible.cpp create mode 100644 examples/from_json__default_constructible.output create mode 100644 examples/from_json__non_default_constructible.cpp create mode 100644 examples/from_json__non_default_constructible.output create mode 100644 examples/from_msgpack.cpp create mode 100644 examples/from_msgpack.output create mode 100644 examples/from_ubjson.cpp create mode 100644 examples/from_ubjson.output create mode 100644 examples/front.cpp create mode 100644 examples/front.output create mode 100644 examples/get__PointerType.cpp create mode 100644 examples/get__PointerType.output create mode 100644 examples/get__ValueType_const.cpp create mode 100644 examples/get__ValueType_const.output create mode 100644 examples/get_allocator.cpp create mode 100644 examples/get_allocator.output create mode 100644 examples/get_binary.cpp create mode 100644 examples/get_binary.output create mode 100644 examples/get_ptr.cpp create mode 100644 examples/get_ptr.output create mode 100644 examples/get_ref.cpp create mode 100644 examples/get_ref.output create mode 100644 examples/get_to.cpp create mode 100644 examples/get_to.output create mode 100644 examples/insert.cpp create mode 100644 examples/insert.output create mode 100644 examples/insert__count.cpp create mode 100644 examples/insert__count.output create mode 100644 examples/insert__ilist.cpp create mode 100644 examples/insert__ilist.output create mode 100644 examples/insert__range.cpp create mode 100644 examples/insert__range.output create mode 100644 examples/insert__range_object.cpp create mode 100644 examples/insert__range_object.output create mode 100644 examples/invalid_iterator.cpp create mode 100644 examples/invalid_iterator.output create mode 100644 examples/is_array.cpp create mode 100644 examples/is_array.output create mode 100644 examples/is_binary.cpp create mode 100644 examples/is_binary.output create mode 100644 examples/is_boolean.cpp create mode 100644 examples/is_boolean.output create mode 100644 examples/is_discarded.cpp create mode 100644 examples/is_discarded.output create mode 100644 examples/is_null.cpp create mode 100644 examples/is_null.output create mode 100644 examples/is_number.cpp create mode 100644 examples/is_number.output create mode 100644 examples/is_number_float.cpp create mode 100644 examples/is_number_float.output create mode 100644 examples/is_number_integer.cpp create mode 100644 examples/is_number_integer.output create mode 100644 examples/is_number_unsigned.cpp create mode 100644 examples/is_number_unsigned.output create mode 100644 examples/is_object.cpp create mode 100644 examples/is_object.output create mode 100644 examples/is_primitive.cpp create mode 100644 examples/is_primitive.output create mode 100644 examples/is_string.cpp create mode 100644 examples/is_string.output create mode 100644 examples/is_structured.cpp create mode 100644 examples/is_structured.output create mode 100644 examples/items.cpp create mode 100644 examples/items.output create mode 100644 examples/json_base_class_t.cpp create mode 100644 examples/json_base_class_t.output create mode 100644 examples/json_lines.cpp create mode 100644 examples/json_lines.output create mode 100644 examples/json_pointer.cpp create mode 100644 examples/json_pointer.output create mode 100644 examples/json_pointer__back.cpp create mode 100644 examples/json_pointer__back.output create mode 100644 examples/json_pointer__empty.cpp create mode 100644 examples/json_pointer__empty.output create mode 100644 examples/json_pointer__operator__equal.cpp create mode 100644 examples/json_pointer__operator__equal.output create mode 100644 examples/json_pointer__operator__equal_stringtype.cpp create mode 100644 examples/json_pointer__operator__equal_stringtype.output create mode 100644 examples/json_pointer__operator__notequal.cpp create mode 100644 examples/json_pointer__operator__notequal.output create mode 100644 examples/json_pointer__operator__notequal_stringtype.cpp create mode 100644 examples/json_pointer__operator__notequal_stringtype.output create mode 100644 examples/json_pointer__operator_add.cpp create mode 100644 examples/json_pointer__operator_add.output create mode 100644 examples/json_pointer__operator_add_binary.cpp create mode 100644 examples/json_pointer__operator_add_binary.output create mode 100644 examples/json_pointer__operator_string_t.cpp create mode 100644 examples/json_pointer__operator_string_t.output create mode 100644 examples/json_pointer__parent_pointer.cpp create mode 100644 examples/json_pointer__parent_pointer.output create mode 100644 examples/json_pointer__pop_back.cpp create mode 100644 examples/json_pointer__pop_back.output create mode 100644 examples/json_pointer__push_back.cpp create mode 100644 examples/json_pointer__push_back.output create mode 100644 examples/json_pointer__string_t.cpp create mode 100644 examples/json_pointer__string_t.output create mode 100644 examples/json_pointer__to_string.cpp create mode 100644 examples/json_pointer__to_string.output create mode 100644 examples/max_size.cpp create mode 100644 examples/max_size.output create mode 100644 examples/merge_patch.cpp create mode 100644 examples/merge_patch.output create mode 100644 examples/meta.cpp create mode 100644 examples/meta.output create mode 100644 examples/nlohmann_define_type_intrusive_explicit.cpp create mode 100644 examples/nlohmann_define_type_intrusive_explicit.output create mode 100644 examples/nlohmann_define_type_intrusive_macro.cpp create mode 100644 examples/nlohmann_define_type_intrusive_macro.output create mode 100644 examples/nlohmann_define_type_intrusive_with_default_explicit.cpp create mode 100644 examples/nlohmann_define_type_intrusive_with_default_explicit.output create mode 100644 examples/nlohmann_define_type_intrusive_with_default_macro.cpp create mode 100644 examples/nlohmann_define_type_intrusive_with_default_macro.output create mode 100644 examples/nlohmann_define_type_non_intrusive_explicit.cpp create mode 100644 examples/nlohmann_define_type_non_intrusive_explicit.output create mode 100644 examples/nlohmann_define_type_non_intrusive_macro.cpp create mode 100644 examples/nlohmann_define_type_non_intrusive_macro.output create mode 100644 examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp create mode 100644 examples/nlohmann_define_type_non_intrusive_with_default_explicit.output create mode 100644 examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp create mode 100644 examples/nlohmann_define_type_non_intrusive_with_default_macro.output create mode 100644 examples/nlohmann_json_namespace.cpp create mode 100644 examples/nlohmann_json_namespace.output create mode 100644 examples/nlohmann_json_namespace_begin.c++17.cpp create mode 100644 examples/nlohmann_json_namespace_begin.c++17.output create mode 100644 examples/nlohmann_json_namespace_no_version.cpp create mode 100644 examples/nlohmann_json_namespace_no_version.output create mode 100644 examples/nlohmann_json_serialize_enum.cpp create mode 100644 examples/nlohmann_json_serialize_enum.output create mode 100644 examples/nlohmann_json_serialize_enum_2.cpp create mode 100644 examples/nlohmann_json_serialize_enum_2.output create mode 100644 examples/nlohmann_json_version.cpp create mode 100644 examples/nlohmann_json_version.output create mode 100644 examples/number_float_t.cpp create mode 100644 examples/number_float_t.output create mode 100644 examples/number_integer_t.cpp create mode 100644 examples/number_integer_t.output create mode 100644 examples/number_unsigned_t.cpp create mode 100644 examples/number_unsigned_t.output create mode 100644 examples/object.cpp create mode 100644 examples/object.output create mode 100644 examples/object_comparator_t.cpp create mode 100644 examples/object_comparator_t.output create mode 100644 examples/object_t.cpp create mode 100644 examples/object_t.output create mode 100644 examples/operator__ValueType.cpp create mode 100644 examples/operator__ValueType.output create mode 100644 examples/operator__equal.cpp create mode 100644 examples/operator__equal.output create mode 100644 examples/operator__equal__nullptr_t.cpp create mode 100644 examples/operator__equal__nullptr_t.output create mode 100644 examples/operator__equal__specializations.cpp create mode 100644 examples/operator__equal__specializations.output create mode 100644 examples/operator__greater.cpp create mode 100644 examples/operator__greater.output create mode 100644 examples/operator__greaterequal.cpp create mode 100644 examples/operator__greaterequal.output create mode 100644 examples/operator__less.cpp create mode 100644 examples/operator__less.output create mode 100644 examples/operator__lessequal.cpp create mode 100644 examples/operator__lessequal.output create mode 100644 examples/operator__notequal.cpp create mode 100644 examples/operator__notequal.output create mode 100644 examples/operator__notequal__nullptr_t.cpp create mode 100644 examples/operator__notequal__nullptr_t.output create mode 100644 examples/operator__value_t.cpp create mode 100644 examples/operator__value_t.output create mode 100644 examples/operator_array__json_pointer.cpp create mode 100644 examples/operator_array__json_pointer.output create mode 100644 examples/operator_array__json_pointer_const.cpp create mode 100644 examples/operator_array__json_pointer_const.output create mode 100644 examples/operator_array__keytype.c++17.cpp create mode 100644 examples/operator_array__keytype.c++17.output create mode 100644 examples/operator_array__keytype_const.c++17.cpp create mode 100644 examples/operator_array__keytype_const.c++17.output create mode 100644 examples/operator_array__object_t_key_type.cpp create mode 100644 examples/operator_array__object_t_key_type.output create mode 100644 examples/operator_array__object_t_key_type_const.cpp create mode 100644 examples/operator_array__object_t_key_type_const.output create mode 100644 examples/operator_array__size_type.cpp create mode 100644 examples/operator_array__size_type.output create mode 100644 examples/operator_array__size_type_const.cpp create mode 100644 examples/operator_array__size_type_const.output create mode 100644 examples/operator_deserialize.cpp create mode 100644 examples/operator_deserialize.output create mode 100644 examples/operator_literal_json.cpp create mode 100644 examples/operator_literal_json.output create mode 100644 examples/operator_literal_json_pointer.cpp create mode 100644 examples/operator_literal_json_pointer.output create mode 100644 examples/operator_ltlt__basic_json.cpp create mode 100644 examples/operator_ltlt__basic_json.output create mode 100644 examples/operator_ltlt__json_pointer.cpp create mode 100644 examples/operator_ltlt__json_pointer.output create mode 100644 examples/operator_spaceship__const_reference.c++20.cpp create mode 100644 examples/operator_spaceship__const_reference.c++20.output create mode 100644 examples/operator_spaceship__scalartype.c++20.cpp create mode 100644 examples/operator_spaceship__scalartype.c++20.output create mode 100644 examples/ordered_json.cpp create mode 100644 examples/ordered_json.output create mode 100644 examples/ordered_map.cpp create mode 100644 examples/ordered_map.output create mode 100644 examples/other_error.cpp create mode 100644 examples/other_error.output create mode 100644 examples/out_of_range.cpp create mode 100644 examples/out_of_range.output create mode 100644 examples/parse__allow_exceptions.cpp create mode 100644 examples/parse__allow_exceptions.output create mode 100644 examples/parse__array__parser_callback_t.cpp create mode 100644 examples/parse__array__parser_callback_t.output create mode 100644 examples/parse__contiguouscontainer__parser_callback_t.cpp create mode 100644 examples/parse__contiguouscontainer__parser_callback_t.output create mode 100644 examples/parse__istream__parser_callback_t.cpp create mode 100644 examples/parse__istream__parser_callback_t.output create mode 100644 examples/parse__iterator_pair.cpp create mode 100644 examples/parse__iterator_pair.output create mode 100644 examples/parse__pointers.cpp create mode 100644 examples/parse__pointers.output create mode 100644 examples/parse__string__parser_callback_t.cpp create mode 100644 examples/parse__string__parser_callback_t.output create mode 100644 examples/parse_error.cpp create mode 100644 examples/parse_error.output create mode 100644 examples/patch.cpp create mode 100644 examples/patch.output create mode 100644 examples/patch_inplace.cpp create mode 100644 examples/patch_inplace.output create mode 100644 examples/push_back.cpp create mode 100644 examples/push_back.output create mode 100644 examples/push_back__initializer_list.cpp create mode 100644 examples/push_back__initializer_list.output create mode 100644 examples/push_back__object_t__value.cpp create mode 100644 examples/push_back__object_t__value.output create mode 100644 examples/rbegin.cpp create mode 100644 examples/rbegin.output create mode 100644 examples/rend.cpp create mode 100644 examples/rend.output create mode 100644 examples/sax_parse.cpp create mode 100644 examples/sax_parse.output create mode 100644 examples/sax_parse__binary.cpp create mode 100644 examples/sax_parse__binary.output create mode 100644 examples/size.cpp create mode 100644 examples/size.output create mode 100644 examples/std_hash.cpp create mode 100644 examples/std_hash.output create mode 100644 examples/std_swap.cpp create mode 100644 examples/std_swap.output create mode 100644 examples/string_t.cpp create mode 100644 examples/string_t.output create mode 100644 examples/swap__array_t.cpp create mode 100644 examples/swap__array_t.output create mode 100644 examples/swap__binary_t.cpp create mode 100644 examples/swap__binary_t.output create mode 100644 examples/swap__object_t.cpp create mode 100644 examples/swap__object_t.output create mode 100644 examples/swap__reference.cpp create mode 100644 examples/swap__reference.output create mode 100644 examples/swap__string_t.cpp create mode 100644 examples/swap__string_t.output create mode 100644 examples/to_bjdata.cpp create mode 100644 examples/to_bjdata.output create mode 100644 examples/to_bson.cpp create mode 100644 examples/to_bson.output create mode 100644 examples/to_cbor.cpp create mode 100644 examples/to_cbor.output create mode 100644 examples/to_json.cpp create mode 100644 examples/to_json.output create mode 100644 examples/to_msgpack.cpp create mode 100644 examples/to_msgpack.output create mode 100644 examples/to_string.cpp create mode 100644 examples/to_string.output create mode 100644 examples/to_ubjson.cpp create mode 100644 examples/to_ubjson.output create mode 100644 examples/type.cpp create mode 100644 examples/type.output create mode 100644 examples/type_error.cpp create mode 100644 examples/type_error.output create mode 100644 examples/type_name.cpp create mode 100644 examples/type_name.output create mode 100644 examples/unflatten.cpp create mode 100644 examples/unflatten.output create mode 100644 examples/update.cpp create mode 100644 examples/update.output create mode 100644 examples/update__range.cpp create mode 100644 examples/update__range.output create mode 100644 examples/value__json_ptr.cpp create mode 100644 examples/value__json_ptr.output create mode 100644 examples/value__keytype.c++17.cpp create mode 100644 examples/value__keytype.c++17.output create mode 100644 examples/value__object_t_key_type.cpp create mode 100644 examples/value__object_t_key_type.output create mode 100644 features/arbitrary_types/index.html create mode 100644 features/assertions/index.html create mode 100644 features/binary_formats/bjdata/index.html create mode 100644 features/binary_formats/bson/index.html create mode 100644 features/binary_formats/cbor/index.html create mode 100644 features/binary_formats/index.html create mode 100644 features/binary_formats/messagepack/index.html create mode 100644 features/binary_formats/ubjson/index.html create mode 100644 features/binary_values/index.html create mode 100644 features/comments/index.html create mode 100644 features/element_access/checked_access/index.html create mode 100644 features/element_access/default_value/index.html create mode 100644 features/element_access/index.html create mode 100644 features/element_access/unchecked_access/index.html create mode 100644 features/enum_conversion/index.html create mode 100644 features/iterators/index.html create mode 100644 features/json_patch/index.html create mode 100644 features/json_pointer/index.html create mode 100644 features/macros/index.html create mode 100644 features/merge_patch/index.html create mode 100644 features/namespace/index.html create mode 100644 features/object_order/index.html create mode 100644 features/parsing/index.html create mode 100644 features/parsing/json_lines/index.html create mode 100644 features/parsing/parse_exceptions/index.html create mode 100644 features/parsing/parser_callbacks/index.html create mode 100644 features/parsing/sax_interface/index.html create mode 100644 features/types/index.html create mode 100644 features/types/number_handling/index.html create mode 100644 home/code_of_conduct/index.html create mode 100644 home/design_goals/index.html create mode 100644 home/exceptions/index.html create mode 100644 home/faq/index.html create mode 100644 home/license/index.html create mode 100644 home/releases/index.html create mode 100644 home/sponsors/index.html create mode 100644 images/callback_events.png create mode 100644 images/json.gif create mode 100644 images/json_syntax_number.png create mode 100644 images/range-begin-end.svg create mode 100644 images/range-rbegin-rend.svg create mode 100644 index.html create mode 100644 integration/cmake/index.html create mode 100644 integration/conan/CMakeLists.txt create mode 100644 integration/conan/Conanfile.txt create mode 100644 integration/conan/example.cpp create mode 100644 integration/example.cpp create mode 100644 integration/index.html create mode 100644 integration/migration_guide/index.html create mode 100644 integration/package_managers/index.html create mode 100644 integration/pkg-config/index.html create mode 100644 integration/vcpkg/CMakeLists.txt create mode 100644 integration/vcpkg/example.cpp create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..4f2a571f2 --- /dev/null +++ b/404.html @@ -0,0 +1 @@ + JSON for Modern C++

404 - Not found

\ No newline at end of file diff --git a/api/adl_serializer/from_json/index.html b/api/adl_serializer/from_json/index.html new file mode 100644 index 000000000..b12ac5898 --- /dev/null +++ b/api/adl_serializer/from_json/index.html @@ -0,0 +1,104 @@ + from_json - JSON for Modern C++
Skip to content

nlohmann::adl_serializer::from_json

// (1)
+template<typename BasicJsonType, typename TargetType = ValueType>
+static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
+    noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
+-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
+
+// (2)
+template<typename BasicJsonType, typename TargetType = ValueType>
+static auto from_json(BasicJsonType && j) noexcept(
+noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
+-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
+

This function is usually called by the get() function of the basic_json 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

Copy of the JSON value, converted to ValueType

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<ns::person>() is called.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::person>();
+
+    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 <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::person>
+{
+    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<ns::person>();
+
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/adl_serializer/index.html b/api/adl_serializer/index.html new file mode 100644 index 000000000..2452b112b --- /dev/null +++ b/api/adl_serializer/index.html @@ -0,0 +1,15 @@ + Overview - JSON for Modern C++
Skip to content

nlohmann::adl_serializer

template<typename, typename>
+struct adl_serializer;
+

Serializer that uses ADL (Argument-Dependent Lookup) to choose to_json/from_json functions from the types' namespaces.

It is implemented similar to

template<typename ValueType>
+struct adl_serializer {
+    template<typename BasicJsonType>
+    static void to_json(BasicJsonType& j, const T& value) {
+        // calls the "to_json" method in T's namespace
+    }
+
+    template<typename BasicJsonType>
+    static void from_json(const BasicJsonType& j, T& value) {
+        // 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/adl_serializer/to_json/index.html b/api/adl_serializer/to_json/index.html new file mode 100644 index 000000000..eade8bd84 --- /dev/null +++ b/api/adl_serializer/to_json/index.html @@ -0,0 +1,38 @@ + to_json - JSON for Modern C++
Skip to content

nlohmann::adl_serializer::to_json

template<typename BasicJsonType, typename TargetType = ValueType>
+static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
+    noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
+-> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
+

This function is usually called by the constructors of the basic_json 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 2.1.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/accept/index.html b/api/basic_json/accept/index.html new file mode 100644 index 000000000..df99a3d00 --- /dev/null +++ b/api/basic_json/accept/index.html @@ -0,0 +1,37 @@ + accept - JSON for Modern C++
Skip to content

nlohmann::basic_json::accept

// (1)
+template<typename InputType>
+static bool accept(InputType&& i,
+                   const bool ignore_comments = false);
+
+// (2)
+template<typename IteratorType>
+static bool accept(IteratorType first, IteratorType last,
+                   const bool ignore_comments = 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 size of 1, 2 or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.

Unlike the parse 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 (must not be null)
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • 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<std::uint8_t>::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)
first (in)
iterator to start of character range
last (in)
iterator to end of 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.

Complexity

Linear in the length of the input. The parser is a predictive LL(1) parser.

Notes

(1) A UTF-8 byte order mark is silently ignored.

Runtime assertion

The precondition that a passed FILE pointer must not be null is enforced with a runtime assertion.

Examples

Example

The example below demonstrates the accept() function reading from a string.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 - deserialize from a compatible input
  • operator>> - deserialize from stream

Version history

  • Added in version 3.0.0.
  • Ignoring comments via ignore_comments added in version 3.9.0.

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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/array/index.html b/api/basic_json/array/index.html new file mode 100644 index 000000000..265b7c462 --- /dev/null +++ b/api/basic_json/array/index.html @@ -0,0 +1,25 @@ + array - JSON for Modern C++
Skip to content

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)). 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.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/array_t/index.html b/api/basic_json/array_t/index.html new file mode 100644 index 000000000..71cfe843a --- /dev/null +++ b/api/basic_json/array_t/index.html @@ -0,0 +1,17 @@ + array_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::array_t

using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
+

The type used to store JSON arrays.

RFC 8259 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<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.

Examples

Example

The following code shows that array_t is by default, a typedef to std::vector<nlohmann::json>.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/at/index.html b/api/basic_json/at/index.html new file mode 100644 index 000000000..58e96c34c --- /dev/null +++ b/api/basic_json/at/index.html @@ -0,0 +1,508 @@ + at - JSON for Modern C++
Skip to content

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<typename KeyType>
+reference at(KeyType&& key);
+template<typename KeyType>
+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 typename object_t::key_type and 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 that is comparable with string_t using object_comparator_t. 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 if the JSON value is not an array; in this case, calling at with an index makes no sense. See example below.
    • Throws out_of_range.401 if the index idx is out of range of the array; that is, idx >= size(). See example below.
  2. The function can throw the following exceptions:
    • Throws type_error.304 if the JSON value is not an object; in this case, calling at with a key makes no sense. See example below.
    • Throws out_of_range.403 if the key key is not stored in the object; that is, find(key) == end(). See example below.
  3. See 2.
  4. The function can throw the following exceptions:
    • Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. See example below.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. See example below.
    • Throws out_of_range.401 if an array index in the passed JSON pointer ptr is out of range. See example below.
    • Throws out_of_range.402 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 example below.
    • Throws out_of_range.403 if the JSON pointer describes a key of an object which cannot be found. See example below.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved. See example below.

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: (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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 (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 (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: (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 (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 (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 (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 (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 (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 (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 (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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/back/index.html b/api/basic_json/back/index.html new file mode 100644 index 000000000..63fd60c69 --- /dev/null +++ b/api/basic_json/back/index.html @@ -0,0 +1,52 @@ + back - JSON for Modern C++
Skip to content

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 case of a structured type (array or object), a reference to the last element is returned. In 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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/basic_json/index.html b/api/basic_json/basic_json/index.html new file mode 100644 index 000000000..aa8607af3 --- /dev/null +++ b/api/basic_json/basic_json/index.html @@ -0,0 +1,462 @@ + (Constructor) - JSON for Modern C++
Skip to content

nlohmann::basic_json::basic_json

// (1)
+basic_json(const value_t v);
+
+// (2)
+basic_json(std::nullptr_t = nullptr) noexcept;
+
+// (3)
+template<typename CompatibleType>
+basic_json(CompatibleType&& val) noexcept(noexcept(
+           JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
+                                      std::forward<CompatibleType>(val))));
+
+// (4)
+template<typename BasicJsonType>
+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().

  2. 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.

  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<U>::to_json method with U = uncvref_t<CompatibleType>, to be exact).

    Template type CompatibleType includes, but is not limited to, the following types:

    • arrays: array_t 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 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_unsigned_t, number_float_t, 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<uint8_t> 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 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 {} 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 JSON object type, so interpreting it as 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() and object() 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 depends on the different types a JSON value can have:

    • In case of a null type, invalid_iterator.206 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 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 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<U> (with U = uncvref_t<CompatibleType>) 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<CompatibleType>

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)
begin of the range to copy from (included)
last (in)
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), 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), 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 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.
  6. (none)
  7. The function can throw the following exceptions:
    • Throws invalid_iterator.201 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 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 example code below.
    • Throws invalid_iterator.206 if iterators first and last belong to a 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:

    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.
    • 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.

  • 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <deque>
+#include <list>
+#include <forward_list>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
+#include <valarray>
+#include <nlohmann/json.hpp>
+
+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<std::string, int> c_map
+    {
+        {"one", 1}, {"two", 2}, {"three", 3}
+    };
+    json j_map(c_map);
+
+    // create an object from std::unordered_map
+    std::unordered_map<const char*, double> c_umap
+    {
+        {"one", 1.2}, {"two", 2.3}, {"three", 3.4}
+    };
+    json j_umap(c_umap);
+
+    // create an object from std::multimap
+    std::multimap<std::string, bool> 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<std::string, bool> 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<int> c_vector {1, 2, 3, 4};
+    json j_vec(c_vector);
+
+    // create an array from std::valarray
+    std::valarray<short> c_valarray {10, 9, 8, 7};
+    json j_valarray(c_valarray);
+
+    // create an array from std::deque
+    std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6};
+    json j_deque(c_deque);
+
+    // create an array from std::list
+    std::list<bool> c_list {true, true, false, true};
+    json j_list(c_list);
+
+    // create an array from std::forward_list
+    std::forward_list<std::int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
+    json j_flist(c_flist);
+
+    // create an array from std::array
+    std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
+    json j_array(c_array);
+
+    // create an array from std::set
+    std::set<std::string> 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<std::string> 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<std::string> 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<std::string> 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 given value

The following code shows examples for creating arrays with several copies of a given value.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.
  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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/begin/index.html b/api/basic_json/begin/index.html new file mode 100644 index 000000000..e0072760c --- /dev/null +++ b/api/basic_json/begin/index.html @@ -0,0 +1,20 @@ + begin - JSON for Modern C++
Skip to content

nlohmann::basic_json::begin

iterator begin() noexcept;
+const_iterator begin() const noexcept;
+

Returns an iterator to the first element.

Illustration from cppreference.com

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/binary/index.html b/api/basic_json/binary/index.html new file mode 100644 index 000000000..47decae65 --- /dev/null +++ b/api/basic_json/binary/index.html @@ -0,0 +1,27 @@ + binary - JSON for Modern C++
Skip to content

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.
  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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create a binary vector
+    std::vector<std::uint8_t> 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/binary_t/index.html b/api/basic_json/binary_t/index.html new file mode 100644 index 000000000..bfe16b114 --- /dev/null +++ b/api/basic_json/binary_t/index.html @@ -0,0 +1,13 @@ + binary_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::binary_t

using binary_t = byte_container_with_subtype<BinaryType>;
+

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.

CBOR's RFC 7049 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 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 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<std::uint8_t>, 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<std::uint8_t>.

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 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 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<std::vector<std::uint8_t>>.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    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 type of subtype to std::uint64_t in version 3.10.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/boolean_t/index.html b/api/basic_json/boolean_t/index.html new file mode 100644 index 000000000..2ec184e14 --- /dev/null +++ b/api/basic_json/boolean_t/index.html @@ -0,0 +1,13 @@ + boolean_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::boolean_t

using boolean_t = BooleanType;
+

The type used to store JSON booleans.

RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false.

To store objects 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    std::cout << std::boolalpha << std::is_same<bool, json::boolean_t>::value << std::endl;
+}
+

Output:

true
+

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/cbegin/index.html b/api/basic_json/cbegin/index.html new file mode 100644 index 000000000..3f5dec2d3 --- /dev/null +++ b/api/basic_json/cbegin/index.html @@ -0,0 +1,19 @@ + cbegin - JSON for Modern C++
Skip to content

nlohmann::basic_json::cbegin

const_iterator cbegin() const noexcept;
+

Returns an iterator to the first element.

Illustration from cppreference.com

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/cbor_tag_handler_t/index.html b/api/basic_json/cbor_tag_handler_t/index.html new file mode 100644 index 000000000..cfae4ed22 --- /dev/null +++ b/api/basic_json/cbor_tag_handler_t/index.html @@ -0,0 +1,38 @@ + cbor_tag_handler_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::cbor_tag_handler_t

enum class cbor_tag_handler_t
+{
+    error,
+    ignore,
+    store
+};
+

This enumeration is used in the from_cbor 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 when reading a tagged byte string.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // tagged byte string
+    std::vector<std::uint8_t> 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 (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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/cend/index.html b/api/basic_json/cend/index.html new file mode 100644 index 000000000..4124f8685 --- /dev/null +++ b/api/basic_json/cend/index.html @@ -0,0 +1,22 @@ + cend - JSON for Modern C++
Skip to content

nlohmann::basic_json::cend

const_iterator cend() const noexcept;
+

Returns an iterator to one past the last element.

Illustration from cppreference.com

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/clear/index.html b/api/basic_json/clear/index.html new file mode 100644 index 000000000..a0129254d --- /dev/null +++ b/api/basic_json/clear/index.html @@ -0,0 +1,44 @@ + clear - JSON for Modern C++
Skip to content

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) would have been called with the current value type from type():

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/contains/index.html b/api/basic_json/contains/index.html new file mode 100644 index 000000000..0eff9a57d --- /dev/null +++ b/api/basic_json/contains/index.html @@ -0,0 +1,104 @@ + contains - JSON for Modern C++
Skip to content

nlohmann::basic_json::contains

// (1)
+bool contains(const typename object_t::key_type& key) const;
+
+// (2)
+template<typename KeyType>
+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.
  2. 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.
  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 that is comparable with string_t using object_comparator_t. 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 key is found or the JSON value is not an object, false is returned.
  2. See 1.
  3. 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.
  2. The function does not throw exceptions.
  3. The function can throw the following 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (json::parse_error& e)
+    {
+        std::cout << e.what() << '\n';
+    }
+}
+

Output:

true
+true
+true
+true
+false
+false
+false
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/count/index.html b/api/basic_json/count/index.html new file mode 100644 index 000000000..b61f6d52a --- /dev/null +++ b/api/basic_json/count/index.html @@ -0,0 +1,49 @@ + count - JSON for Modern C++
Skip to content

nlohmann::basic_json::count

// (1)
+size_type count(const typename object_t::key_type& key) const;
+
+// (2)
+template<typename KeyType>
+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 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 that is comparable with string_t using object_comparator_t. 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/crbegin/index.html b/api/basic_json/crbegin/index.html new file mode 100644 index 000000000..7dc4d9381 --- /dev/null +++ b/api/basic_json/crbegin/index.html @@ -0,0 +1,19 @@ + crbegin - JSON for Modern C++
Skip to content

nlohmann::basic_json::crbegin

const_reverse_iterator crbegin() const noexcept;
+

Returns an iterator to the reverse-beginning; that is, the last element.

Illustration from cppreference.com

Return value

reverse 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 crbegin().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/crend/index.html b/api/basic_json/crend/index.html new file mode 100644 index 000000000..ff5eeab01 --- /dev/null +++ b/api/basic_json/crend/index.html @@ -0,0 +1,22 @@ + crend - JSON for Modern C++
Skip to content

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.

Illustration from cppreference.com

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 eend().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/default_object_comparator_t/index.html b/api/basic_json/default_object_comparator_t/index.html new file mode 100644 index 000000000..0213ebc7f --- /dev/null +++ b/api/basic_json/default_object_comparator_t/index.html @@ -0,0 +1,17 @@ + default_object_comparator_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::default_object_comparator_t

using default_object_comparator_t = std::less<StringType>;  // until C++14
+
+using default_object_comparator_t = std::less<>;            // since C++14
+

The default comparator used by object_t.

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 and can be obtained via object_comparator_t.

Examples

Example

The example below demonstrates the default comparator.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/diff/index.html b/api/basic_json/diff/index.html new file mode 100644 index 000000000..c91891812 --- /dev/null +++ b/api/basic_json/diff/index.html @@ -0,0 +1,66 @@ + diff - JSON for Modern C++
Skip to content

nlohmann::basic_json::diff

static basic_json diff(const basic_json& source,
+                       const basic_json& target);
+

Creates a JSON Patch so that value source can be changed into the value target by calling patch 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/dump/index.html b/api/basic_json/dump/index.html new file mode 100644 index 000000000..9eb61ab66 --- /dev/null +++ b/api/basic_json/dump/index.html @@ -0,0 +1,108 @@ + dump - JSON for Modern C++
Skip to content

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, 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: strict (throws and 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 bytes are copied to the output unchanged)).

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 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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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: "äü"
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/emplace/index.html b/api/basic_json/emplace/index.html new file mode 100644 index 000000000..1ad46a784 --- /dev/null +++ b/api/basic_json/emplace/index.html @@ -0,0 +1,40 @@ + emplace - JSON for Modern C++
Skip to content

nlohmann::basic_json::emplace

template<class... Args>
+std::pair<iterator, bool> 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

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.

Exceptions

Throws type_error.311 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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
+

Version history

  • Since version 2.0.8.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/emplace_back/index.html b/api/basic_json/emplace_back/index.html new file mode 100644 index 000000000..6ddbad094 --- /dev/null +++ b/api/basic_json/emplace_back/index.html @@ -0,0 +1,31 @@ + emplace_back - JSON for Modern C++
Skip to content

nlohmann::basic_json::emplace_back

template<class... Args>
+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

Parameters

args (in)
arguments to forward to a constructor of basic_json

Return value

reference to the inserted element

Exceptions

Throws type_error.311 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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"]]
+

Version history

  • Since version 2.0.8.
  • Returns reference since 3.7.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/empty/index.html b/api/basic_json/empty/index.html new file mode 100644 index 000000000..3304fae3e --- /dev/null +++ b/api/basic_json/empty/index.html @@ -0,0 +1,45 @@ + empty - JSON for Modern C++
Skip to content

nlohmann::basic_json::empty

bool empty() const noexcept;
+

Checks if a JSON value has no elements (i.e. whether its size() 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 and object_t satisfy the 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/end/index.html b/api/basic_json/end/index.html new file mode 100644 index 000000000..0c03f814f --- /dev/null +++ b/api/basic_json/end/index.html @@ -0,0 +1,23 @@ + end - JSON for Modern C++
Skip to content

nlohmann::basic_json::end

iterator end() noexcept;
+const_iterator end() const noexcept;
+

Returns an iterator to one past the last element.

Illustration from cppreference.com

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/erase/index.html b/api/basic_json/erase/index.html new file mode 100644 index 000000000..ab5ebaac3 --- /dev/null +++ b/api/basic_json/erase/index.html @@ -0,0 +1,151 @@ + erase - JSON for Modern C++
Skip to content

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<typename KeyType>
+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.

  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 null, the resulting JSON value will be null.

  3. Removes an element from a JSON object by key.

  4. 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.

  5. Removes an element from a JSON array by index.

Template parameters

KeyType
A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t. 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 if called on a null value; example: "cannot use erase() with null"
    • Throws invalid_iterator.202 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 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 if called on a null value; example: "cannot use erase() with null"
    • Throws invalid_iterator.203 if called on iterators which does not belong to the current JSON value; example: "iterators do not fit current value"
    • Throws invalid_iterator.204 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 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 when called on a type other than JSON object; example: "cannot use erase() with null"
    • Throws out_of_range.401 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: (1) remove element given an iterator

The example shows the effect of erase() for different JSON types using an iterator.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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]
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/error_handler_t/index.html b/api/basic_json/error_handler_t/index.html new file mode 100644 index 000000000..a0d39e32a --- /dev/null +++ b/api/basic_json/error_handler_t/index.html @@ -0,0 +1,33 @@ + error_handler_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::error_handler_t

enum class error_handler_t {
+    strict,
+    replace,
+    ignore
+};
+

This enumeration is used in the dump 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 bytes are copied to the output unchanged

Examples

Example

The example below shows how the different values of the error_handler_t influence the behavior of dump when reading serializing an invalid UTF-8 sequence.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/exception/index.html b/api/basic_json/exception/index.html new file mode 100644 index 000000000..0c200c45d --- /dev/null +++ b/api/basic_json/exception/index.html @@ -0,0 +1,24 @@ + exception - JSON for Modern C++
Skip to content

nlohmann::basic_json::exception

class exception : public std::exception;
+

This class is an extension of std::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.

uml diagram

Subclasses:

  • parse_error for exceptions indicating a parse error
  • invalid_iterator for exceptions indicating errors with iterators
  • type_error for exceptions indicating executing a member function with a wrong type
  • out_of_range for exceptions indicating access out of the defined range
  • other_error 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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

Version history

  • Since version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/find/index.html b/api/basic_json/find/index.html new file mode 100644 index 000000000..27d86d994 --- /dev/null +++ b/api/basic_json/find/index.html @@ -0,0 +1,58 @@ + find - JSON for Modern C++
Skip to content

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<typename KeyType>
+iterator find(KeyType&& key);
+template<typename KeyType>
+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 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 that is comparable with string_t using object_comparator_t. 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/flatten/index.html b/api/basic_json/flatten/index.html new file mode 100644 index 000000000..594a413d0 --- /dev/null +++ b/api/basic_json/flatten/index.html @@ -0,0 +1,46 @@ + flatten - JSON for Modern C++
Skip to content

nlohmann::basic_json::flatten

basic_json flatten() const;
+

The function creates a JSON object whose keys are JSON pointers (see RFC 6901) and whose values are all primitive (see is_primitive() for more information). The original JSON value can be restored using the unflatten() 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 the JSON value.

Notes

Empty objects and arrays are flattened to null and will not be reconstructed correctly by the unflatten() function.

Examples

Example

The following code shows how a JSON object is flattened to an object whose keys consist of JSON pointers.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/from_bjdata/index.html b/api/basic_json/from_bjdata/index.html new file mode 100644 index 000000000..f9cfa0562 --- /dev/null +++ b/api/basic_json/from_bjdata/index.html @@ -0,0 +1,35 @@ + from_bjdata - JSON for Modern C++
Skip to content

nlohmann::basic_json::from_bjdata

// (1)
+template<typename InputType>
+static basic_json from_bjdata(InputType&& i,
+                              const bool strict = true,
+                              const bool allow_exceptions = true);
+// (2)
+template<typename IteratorType>
+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 is described on a dedicated page.

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 start of the input
last (in)
iterator to 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.

Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

Exceptions

  • Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true
  • Throws parse_error.112 if a parse error occurs
  • Throws parse_error.113 if a string could not be parsed successfully

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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create byte vector
+    std::vector<std::uint8_t> 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
+}
+

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/from_bson/index.html b/api/basic_json/from_bson/index.html new file mode 100644 index 000000000..a4089a375 --- /dev/null +++ b/api/basic_json/from_bson/index.html @@ -0,0 +1,36 @@ + from_bson - JSON for Modern C++
Skip to content

nlohmann::basic_json::from_bson

// (1)
+template<typename InputType>
+static basic_json from_bson(InputType&& i,
+                            const bool strict = true,
+                            const bool allow_exceptions = true);
+// (2)
+template<typename IteratorType>
+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 is described on a dedicated page.

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 start of the input
last (in)
iterator to 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.

Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

Exceptions

Throws parse_error.114 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create byte vector
+    std::vector<std::uint8_t> 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

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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/from_cbor/index.html b/api/basic_json/from_cbor/index.html new file mode 100644 index 000000000..97d2b272e --- /dev/null +++ b/api/basic_json/from_cbor/index.html @@ -0,0 +1,38 @@ + from_cbor - JSON for Modern C++
Skip to content

nlohmann::basic_json::from_cbor

// (1)
+template<typename InputType>
+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<typename IteratorType>
+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 is described on a dedicated page.

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 start of the input
last (in)
iterator to 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 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.

Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

Exceptions

  • Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true
  • Throws parse_error.112 if unsupported features from CBOR were used in the given input or if the input is not valid CBOR
  • Throws parse_error.113 if a string was expected as 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create byte vector
+    std::vector<std::uint8_t> 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
+}
+

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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/from_msgpack/index.html b/api/basic_json/from_msgpack/index.html new file mode 100644 index 000000000..c79ef4abf --- /dev/null +++ b/api/basic_json/from_msgpack/index.html @@ -0,0 +1,35 @@ + from_msgpack - JSON for Modern C++
Skip to content

nlohmann::basic_json::from_msgpack

// (1)
+template<typename InputType>
+static basic_json from_msgpack(InputType&& i,
+                               const bool strict = true,
+                               const bool allow_exceptions = true);
+// (2)
+template<typename IteratorType>
+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 is described on a dedicated page.

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 start of the input
last (in)
iterator to 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.

Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

Exceptions

  • Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true
  • Throws parse_error.112 if unsupported features from MessagePack were used in the given input or if the input is not valid MessagePack
  • Throws parse_error.113 if a string was expected as 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create byte vector
+    std::vector<std::uint8_t> 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
+}
+

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_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_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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/from_ubjson/index.html b/api/basic_json/from_ubjson/index.html new file mode 100644 index 000000000..5f9211b38 --- /dev/null +++ b/api/basic_json/from_ubjson/index.html @@ -0,0 +1,35 @@ + from_ubjson - JSON for Modern C++
Skip to content

nlohmann::basic_json::from_ubjson

// (1)
+template<typename InputType>
+static basic_json from_ubjson(InputType&& i,
+                              const bool strict = true,
+                              const bool allow_exceptions = true);
+// (2)
+template<typename IteratorType>
+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 is described on a dedicated page.

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 start of the input
last (in)
iterator to 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.

Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

Exceptions

  • Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true
  • Throws parse_error.112 if a parse error occurs
  • Throws parse_error.113 if a string could not be parsed successfully

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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create byte vector
+    std::vector<std::uint8_t> 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
+}
+

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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/front/index.html b/api/basic_json/front/index.html new file mode 100644 index 000000000..6fb61d035 --- /dev/null +++ b/api/basic_json/front/index.html @@ -0,0 +1,38 @@ + front - JSON for Modern C++
Skip to content

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 case of a structured type (array or object), a reference to the first element is returned. In 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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/get/index.html b/api/basic_json/get/index.html new file mode 100644 index 000000000..a8581b713 --- /dev/null +++ b/api/basic_json/get/index.html @@ -0,0 +1,106 @@ + get - JSON for Modern C++
Skip to content

nlohmann::basic_json::get

// (1)
+template<typename ValueType>
+ValueType get() const noexcept(
+    noexcept(JSONSerializer<ValueType>::from_json(
+        std::declval<const basic_json_t&>(), std::declval<ValueType&>())));
+
+// (2)
+template<typename BasicJsonType>
+BasicJsonType get() const;
+
+// (3)
+template<typename PointerType>
+PointerType get_ptr();
+
+template<typename PointerType>
+constexpr const PointerType get_ptr() const noexcept;
+
  1. Explicit type conversion between the JSON value and a compatible value which is CopyConstructible and DefaultConstructible. The value is converted by calling the json_serializer<ValueType> from_json() method.

    The function is equivalent to executing

    ValueType ret;
    +JSONSerializer<ValueType>::from_json(*this, ret);
    +return ret;
    +

    This overload is chosen if:

    • ValueType is not basic_json,
    • json_serializer<ValueType> has a from_json() method of the form void from_json(const basic_json&, ValueType&), and
    • json_serializer<ValueType> does not have a from_json() method of the form ValueType from_json(const basic_json&)

    If the type is not CopyConstructible and not DefaultConstructible, the value is converted by calling the json_serializer<ValueType> from_json() method.

    The function is then equivalent to executing

    return JSONSerializer<ValueTypeCV>::from_json(*this);
    +

    This overload is chosen if:

    • ValueType is not basic_json and
    • json_serializer<ValueType> has a from_json() method of the form ValueType from_json(const basic_json&)

    If json_serializer<ValueType> has both overloads of from_json(), the latter one is chosen.

  2. Overload for basic_json specializations. The function is equivalent to executing

    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, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. Other types will not compile.

Return value

  1. copy of the JSON value, converted to ValueType
  2. a copy of *this, converted into BasicJsonType
  3. 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<ValueType> from_json() method throws

Notes

Undefined behavior

Writing data to the pointee (overload 3) of the result yields an undefined state.

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<short>, (3) A JSON object can be converted to C++ associative containers such as std::unordered_map<std::string, json>.

#include <iostream>
+#include <unordered_map>
+#include <nlohmann/json.hpp>
+
+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<bool>();
+    auto v2 = json_types["number"]["integer"].get<int>();
+    auto v3 = json_types["number"]["integer"].get<short>();
+    auto v4 = json_types["number"]["floating-point"].get<float>();
+    auto v5 = json_types["number"]["floating-point"].get<int>();
+    auto v6 = json_types["string"].get<std::string>();
+    auto v7 = json_types["array"].get<std::vector<short>>();
+    auto v8 = json_types.get<std::unordered_map<std::string, json>>();
+
+    // 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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create a JSON number
+    json value = 17;
+
+    // explicitly getting pointers
+    auto p1 = value.get<const json::number_integer_t*>();
+    auto p2 = value.get<json::number_integer_t*>();
+    auto p3 = value.get<json::number_integer_t* const>();
+    auto p4 = value.get<const json::number_integer_t* const>();
+    auto p5 = value.get<json::number_float_t*>();
+
+    // print the pointees
+    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n';
+    std::cout << std::boolalpha << (p5 == nullptr) << '\n';
+}
+

Output:

17 17 17 17
+true
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/get_allocator/index.html b/api/basic_json/get_allocator/index.html new file mode 100644 index 000000000..0e87399bc --- /dev/null +++ b/api/basic_json/get_allocator/index.html @@ -0,0 +1,21 @@ + get_allocator - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    auto alloc = json::get_allocator();
+    using traits_t = std::allocator_traits<decltype(alloc)>;
+
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/get_binary/index.html b/api/basic_json/get_binary/index.html new file mode 100644 index 000000000..d86dbe747 --- /dev/null +++ b/api/basic_json/get_binary/index.html @@ -0,0 +1,21 @@ + get_binary - JSON for Modern C++
Skip to content

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 if the value is not binary

Complexity

Constant.

Examples

Example

The following code shows how to query a binary value.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create a binary vector
+    std::vector<std::uint8_t> 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/get_ptr/index.html b/api/basic_json/get_ptr/index.html new file mode 100644 index 000000000..331495e7c --- /dev/null +++ b/api/basic_json/get_ptr/index.html @@ -0,0 +1,29 @@ + get_ptr - JSON for Modern C++
Skip to content

nlohmann::basic_json::get_ptr

template<typename PointerType>
+PointerType get_ptr() noexcept;
+
+template<typename PointerType>
+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, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. 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

Writing data to the pointee of the result yields an undefined state.

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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create a JSON number
+    json value = 17;
+
+    // explicitly getting pointers
+    auto p1 = value.get_ptr<const json::number_integer_t*>();
+    auto p2 = value.get_ptr<json::number_integer_t*>();
+    auto p3 = value.get_ptr<json::number_integer_t* const>();
+    auto p4 = value.get_ptr<const json::number_integer_t* const>();
+    auto p5 = value.get_ptr<json::number_float_t*>();
+
+    // print the pointees
+    std::cout << *p1 << ' ' << *p2 << ' ' << *p3 << ' ' << *p4 << '\n';
+    std::cout << std::boolalpha << (p5 == nullptr) << '\n';
+}
+

Output:

17 17 17 17
+true
+

Version history

  • Added in version 1.0.0.
  • Extended to binary types in version 3.8.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/get_ref/index.html b/api/basic_json/get_ref/index.html new file mode 100644 index 000000000..731c687db --- /dev/null +++ b/api/basic_json/get_ref/index.html @@ -0,0 +1,35 @@ + get_ref - JSON for Modern C++
Skip to content

nlohmann::basic_json::get_ref

template<typename ReferenceType>
+ReferenceType get_ref();
+
+template<typename ReferenceType>
+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, object_t, string_t, boolean_t, number_integer_t, or number_unsigned_t, number_float_t, or binary_t. 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 otherwise

Exception safety

Strong exception safety: if an exception occurs, the original value stays intact.

Exceptions

Throws type_error.303 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

Writing data to the referee of the result yields an undefined state.

Examples

Example

The example shows several calls to get_ref().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create a JSON number
+    json value = 17;
+
+    // explicitly getting references
+    auto r1 = value.get_ref<const json::number_integer_t&>();
+    auto r2 = value.get_ref<json::number_integer_t&>();
+
+    // print the values
+    std::cout << r1 << ' ' << r2 << '\n';
+
+    // incompatible type throws exception
+    try
+    {
+        auto r3 = value.get_ref<json::number_float_t&>();
+    }
+    catch (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
+

Version history

  • Added in version 1.1.0.
  • Extended to binary types in version 3.8.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/get_to/index.html b/api/basic_json/get_to/index.html new file mode 100644 index 000000000..b270402ba --- /dev/null +++ b/api/basic_json/get_to/index.html @@ -0,0 +1,78 @@ + get_to - JSON for Modern C++
Skip to content

nlohmann::basic_json::get_to

template<typename ValueType>
+ValueType& get_to(ValueType& v) const noexcept(
+    noexcept(JSONSerializer<ValueType>::from_json(
+        std::declval<const basic_json_t&>(), 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<ValueType> from_json() method.

The function is equivalent to executing

ValueType v;
+JSONSerializer<ValueType>::from_json(*this, v);
+

This overload is chosen if:

  • ValueType is not basic_json,
  • json_serializer<ValueType> 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<ValueType> from_json() method throws

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<short>, (3) A JSON object can be converted to C++ associative containers such as #cpp std::unordered_map<std::string, json>.

#include <iostream>
+#include <unordered_map>
+#include <nlohmann/json.hpp>
+
+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<short> v7;
+    std::unordered_map<std::string, json> 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]
+

Version history

  • Since version 3.3.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/index.html b/api/basic_json/index.html new file mode 100644 index 000000000..72d0f3b8f --- /dev/null +++ b/api/basic_json/index.html @@ -0,0 +1,81 @@ + Overview - JSON for Modern C++
Skip to content

nlohmann::basic_json

Defined in header <nlohmann/json.hpp>

template<
+    template<typename U, typename V, typename... Args> class ObjectType = std::map,
+    template<typename U, typename... Args> 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<typename U> class AllocatorType = std::allocator,
+    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,
+    class BinaryType = std::vector<std::uint8_t,
+    class CustomBaseClass = void>
+>
+class basic_json;
+

Template parameters

Template parameter Description Derived type
ObjectType type for JSON objects object_t
ArrayType type for JSON arrays array_t
StringType type for JSON strings and object keys string_t
BooleanType type for JSON booleans boolean_t
NumberIntegerType type for JSON integer numbers number_integer_t
NumberUnsignedType type for JSON unsigned integer numbers number_unsigned_t
NumberFloatType type for JSON floating-point numbers number_float_t
AllocatorType type of the allocator to use
JSONSerializer the serializer to resolve internal calls to to_json() and from_json() json_serializer
BinaryType type for binary arrays binary_t
CustomBaseClass extension point for user code json_base_class_t

Specializations

  • json - default specialization
  • ordered_json - specialization that maintains the insertion order of object keys

Iterator invalidation

Todo

Requirements

The class satisfies the following concept requirements:

Basic

Layout

  • StandardLayoutType: JSON values have 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: JSON values can be compared with ==, see operator==.
  • LessThanComparable: JSON values can be compared with <, see operator<.
  • Swappable: Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of other compatible types, using unqualified function swap.
  • NullablePointer: JSON values can be compared against std::nullptr_t objects which are used to model the null value.

Container

  • Container: JSON values can be used like STL containers and provide iterator access.
  • ReversibleContainer: JSON values can be used like STL containers and provide reverse iterator access.

Member types

Exceptions

  • exception - general exception of the basic_json class
    • parse_error - exception indicating a parse error
    • invalid_iterator - exception indicating errors with iterators
    • type_error - exception indicating executing a member function with a wrong type
    • out_of_range - exception indicating access out of the defined range
    • other_error - 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<basic_json>
pointer std::allocator_traits<allocator_type>::pointer
const_pointer std::allocator_traits<allocator_type>::const_pointer
iterator LegacyBidirectionalIterator
const_iterator constant LegacyBidirectionalIterator
reverse_iterator reverse iterator, derived from iterator
const_reverse_iterator reverse iterator, derived from const_iterator
iteration_proxy helper type for items function

JSON value data types

Parser callback

Member functions

Object inspection

Functions to inspect the type of a JSON value.

Value access

Direct access to the stored value of a JSON value.

Element access

Access to the JSON value

  • at - access specified element with bounds checking
  • operator[] - access specified element
  • value - access specified object element with default value
  • front - access the first element
  • back - access the last element

Lookup

  • find - find an element in a JSON object
  • count - returns the number of occurrences of a key in a JSON object
  • contains - check the existence of an element in a JSON object

Iterators

  • begin - returns an iterator to the first element
  • cbegin - returns a const iterator to the first element
  • end - returns an iterator to one past the last element
  • cend - returns a const iterator to one past the last element
  • rbegin - returns an iterator to the reverse-beginning
  • rend - returns an iterator to the reverse-end
  • crbegin - returns a const iterator to the reverse-beginning
  • crend - returns a const iterator to the reverse-end
  • items - wrapper to access iterator member functions in range-based for

Capacity

  • empty - checks whether the container is empty
  • size - returns the number of elements
  • max_size - returns the maximum possible number of elements

Modifiers

  • clear - clears the contents
  • push_back - add a value to an array/object
  • operator+= - add a value to an array/object
  • emplace_back - add a value to an array
  • emplace - add a value to an object if key does not exist
  • erase - remove elements
  • insert - inserts elements
  • update - updates a JSON object from another object, overwriting existing keys
  • swap - exchanges the values

Lexicographical comparison operators

Serialization / Dumping

  • dump - serialization

Deserialization / Parsing

  • parse (static) - deserialize from a compatible input
  • accept (static) - check if the input is valid JSON
  • sax_parse (static) - generate SAX events

JSON Pointer functions

  • flatten - return flattened JSON value
  • unflatten - unflatten a previously flattened JSON value

JSON Patch functions

  • patch - applies a JSON patch
  • patch_inplace - applies a JSON patch in place
  • diff (static) - creates a diff as a JSON patch

JSON Merge Patch functions

Static functions

  • meta - returns version information on the library
  • get_allocator - returns the allocator associated with the container

Binary formats

  • from_bjdata (static) - create a JSON value from an input in BJData format
  • from_bson (static) - create a JSON value from an input in BSON format
  • from_cbor (static) - create a JSON value from an input in CBOR format
  • from_msgpack (static) - create a JSON value from an input in MessagePack format
  • from_ubjson (static) - create a JSON value from an input in UBJSON format
  • to_bjdata (static) - create a BJData serialization of a given JSON value
  • to_bson (static) - create a BSON serialization of a given JSON value
  • to_cbor (static) - create a CBOR serialization of a given JSON value
  • to_msgpack (static) - create a MessagePack serialization of a given JSON value
  • to_ubjson (static) - create a UBJSON serialization of a given JSON value

Non-member functions

Literals

Helper classes

Examples

Example

The example shows how the library is used.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/input_format_t/index.html b/api/basic_json/input_format_t/index.html new file mode 100644 index 000000000..ae51e0ebd --- /dev/null +++ b/api/basic_json/input_format_t/index.html @@ -0,0 +1,126 @@ + input_format_t - JSON for Modern C++
Skip to content

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 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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<std::uint8_t> 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/insert/index.html b/api/basic_json/insert/index.html new file mode 100644 index 000000000..a131c49bb --- /dev/null +++ b/api/basic_json/insert/index.html @@ -0,0 +1,119 @@ + insert - JSON for Modern C++
Skip to content

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 array before iterator pos.
  2. Inserts cnt copies of val into array before iterator pos.
  3. Inserts elements from range [first, last) into array before iterator pos.
  4. Inserts elements from initializer list ilist into array before iterator pos.
  5. Inserts elements from range [first, last) into object.

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)
begin of the range of elements to insert
last (in)
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 cnt==0
  3. iterator pointing to the first element inserted, or pos if 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 if called on JSON values other than arrays; example: "cannot use insert() with string"
    • Throws invalid_iterator.202 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 if called on JSON values other than arrays; example: "cannot use insert() with string"
    • Throws invalid_iterator.202 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 if called on JSON values other than arrays; example: "cannot use insert() with string"
    • Throws invalid_iterator.202 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 if first and last do not belong to the same JSON value; example: "iterators do not fit"
    • Throws invalid_iterator.211 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 if called on JSON values other than arrays; example: "cannot use insert() with string"
    • Throws invalid_iterator.202 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 if called on JSON values other than objects; example: "cannot use insert() with string"
    • Throws invalid_iterator.202 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 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 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 (1): insert element into array

The example shows how insert() is used.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 range of elements into array

The example shows how insert() is used.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 initializer list into array

The example shows how insert() is used.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 range of elements into object

The example shows how insert() is used.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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"}
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/invalid_iterator/index.html b/api/basic_json/invalid_iterator/index.html new file mode 100644 index 000000000..2e6d0e409 --- /dev/null +++ b/api/basic_json/invalid_iterator/index.html @@ -0,0 +1,25 @@ + invalid_iterator - JSON for Modern C++
Skip to content

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).

uml diagram

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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

Version history

  • Since version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_array/index.html b/api/basic_json/is_array/index.html new file mode 100644 index 000000000..c4e2f11ea --- /dev/null +++ b/api/basic_json/is_array/index.html @@ -0,0 +1,41 @@ + is_array - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_binary/index.html b/api/basic_json/is_binary/index.html new file mode 100644 index 000000000..a0d481cb3 --- /dev/null +++ b/api/basic_json/is_binary/index.html @@ -0,0 +1,41 @@ + is_binary - JSON for Modern C++
Skip to content

nlohmann::basic_json::is_binary

constexpr bool is_binary() const noexcept;
+

This function returns true if and only if the JSON value is 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_boolean/index.html b/api/basic_json/is_boolean/index.html new file mode 100644 index 000000000..a18832fe4 --- /dev/null +++ b/api/basic_json/is_boolean/index.html @@ -0,0 +1,41 @@ + is_boolean - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_discarded/index.html b/api/basic_json/is_discarded/index.html new file mode 100644 index 000000000..bc73e7bb6 --- /dev/null +++ b/api/basic_json/is_discarded/index.html @@ -0,0 +1,43 @@ + is_discarded - JSON for Modern C++
Skip to content

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), or
  • the value is the result of parsing invalid JSON with parameter allow_exceptions set to false; see parse 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==. 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) 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. Only if the top-level value is discarded, the return value of the parse call is discarded.

This function will always be false for JSON values after parsing. That is, discarded values can only occur during parsing, but will be removed when inside a structured value or replaced by null in other cases.

Examples

Example

The following code exemplifies is_discarded() for all JSON types.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_null/index.html b/api/basic_json/is_null/index.html new file mode 100644 index 000000000..1a10dba24 --- /dev/null +++ b/api/basic_json/is_null/index.html @@ -0,0 +1,41 @@ + is_null - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_number/index.html b/api/basic_json/is_number/index.html new file mode 100644 index 000000000..372cce19f --- /dev/null +++ b/api/basic_json/is_number/index.html @@ -0,0 +1,45 @@ + is_number - JSON for Modern C++
Skip to content

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-type), 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_number_float/index.html b/api/basic_json/is_number_float/index.html new file mode 100644 index 000000000..4d6addad1 --- /dev/null +++ b/api/basic_json/is_number_float/index.html @@ -0,0 +1,41 @@ + is_number_float - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_number_integer/index.html b/api/basic_json/is_number_integer/index.html new file mode 100644 index 000000000..3416b079c --- /dev/null +++ b/api/basic_json/is_number_integer/index.html @@ -0,0 +1,41 @@ + is_number_integer - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.
  • Extended to also return true for unsigned integers in 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_number_unsigned/index.html b/api/basic_json/is_number_unsigned/index.html new file mode 100644 index 000000000..48efd697d --- /dev/null +++ b/api/basic_json/is_number_unsigned/index.html @@ -0,0 +1,41 @@ + is_number_unsigned - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_object/index.html b/api/basic_json/is_object/index.html new file mode 100644 index 000000000..eca2a1612 --- /dev/null +++ b/api/basic_json/is_object/index.html @@ -0,0 +1,41 @@ + is_object - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_primitive/index.html b/api/basic_json/is_primitive/index.html new file mode 100644 index 000000000..a47e60e1b --- /dev/null +++ b/api/basic_json/is_primitive/index.html @@ -0,0 +1,45 @@ + is_primitive - JSON for Modern C++
Skip to content

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:

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.
  • Extended to return true for binary types in version 3.8.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_string/index.html b/api/basic_json/is_string/index.html new file mode 100644 index 000000000..4861342c4 --- /dev/null +++ b/api/basic_json/is_string/index.html @@ -0,0 +1,41 @@ + is_string - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/is_structured/index.html b/api/basic_json/is_structured/index.html new file mode 100644 index 000000000..b6034d559 --- /dev/null +++ b/api/basic_json/is_structured/index.html @@ -0,0 +1,45 @@ + is_structured - JSON for Modern C++
Skip to content

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_primitive() const noexcept
+{
+    return is_array() || is_object();
+}
+

Notes

The term structured stems from RFC 8259:

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/items/index.html b/api/basic_json/items/index.html new file mode 100644 index 000000000..9c39221c6 --- /dev/null +++ b/api/basic_json/items/index.html @@ -0,0 +1,50 @@ + items - JSON for Modern C++
Skip to content

nlohmann::basic_json::items

iteration_proxy<iterator> items() noexcept;
+iteration_proxy<const_iterator> 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 (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 https://github.com/nlohmann/json/issues/2040 for more information.

Examples

Example

The following code shows an example for items().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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
+

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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/json_base_class_t/index.html b/api/basic_json/json_base_class_t/index.html new file mode 100644 index 000000000..3eb012332 --- /dev/null +++ b/api/basic_json/json_base_class_t/index.html @@ -0,0 +1,94 @@ + json_base_class_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::json_base_class_t

using json_base_class_t = detail::json_base_class<CustomBaseClass>;
+

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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+class visitor_adaptor_with_metadata
+{
+  public:
+    template <class Fnc>
+    void visit(const Fnc& fnc) const;
+
+    int metadata = 42;
+  private:
+    template <class Ptr, class Fnc>
+    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<std::uint8_t>,
+             visitor_adaptor_with_metadata
+             >;
+
+template <class Fnc>
+void visitor_adaptor_with_metadata::visit(const Fnc& fnc) const
+{
+    do_visit(json::json_pointer{}, fnc);
+}
+
+template <class Ptr, class Fnc>
+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<const json*>(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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/json_serializer/index.html b/api/basic_json/json_serializer/index.html new file mode 100644 index 000000000..4ff083e66 --- /dev/null +++ b/api/basic_json/json_serializer/index.html @@ -0,0 +1,57 @@ + json_serializer - JSON for Modern C++
Skip to content

nlohmann::basic_json::json_serializer

template<typename T, typename SFINAE>
+using json_serializer = JSONSerializer<T, SFINAE>;
+

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.

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::person>
+{
+    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<ns::person>();
+
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/max_size/index.html b/api/basic_json/max_size/index.html new file mode 100644 index 000000000..c4ce33927 --- /dev/null +++ b/api/basic_json/max_size/index.html @@ -0,0 +1,34 @@ + max_size - JSON for Modern C++
Skip to content

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())
boolean 1 (same as size())
string 1 (same as size())
number 1 (same as size())
binary 1 (same as size())
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 and object_t satisfy the 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/merge_patch/index.html b/api/basic_json/merge_patch/index.html new file mode 100644 index 000000000..6b65ecee6 --- /dev/null +++ b/api/basic_json/merge_patch/index.html @@ -0,0 +1,67 @@ + merge_patch - JSON for Modern C++
Skip to content

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):

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 <iostream>
+#include <nlohmann/json.hpp>
+#include <iomanip> // 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

Version history

  • Added in version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/meta/index.html b/api/basic_json/meta/index.html new file mode 100644 index 000000000..4ed2ad67d --- /dev/null +++ b/api/basic_json/meta/index.html @@ -0,0 +1,30 @@ + meta - JSON for Modern C++
Skip to content

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).
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, 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // call meta()
+    std::cout << std::setw(4) << json::meta() << '\n';
+}
+

Output:

{
+    "compiler": {
+        "c++": "201103",
+        "family": "gcc",
+        "version": "12.1.0"
+    },
+    "copyright": "(C) 2013-2022 Niels Lohmann",
+    "name": "JSON for Modern C++",
+    "platform": "apple",
+    "url": "https://github.com/nlohmann/json",
+    "version": {
+        "major": 3,
+        "minor": 11,
+        "patch": 2,
+        "string": "3.11.2"
+    }
+}
+

Note the output is platform-dependent.

See also

Version history

  • Added in version 2.1.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/number_float_t/index.html b/api/basic_json/number_float_t/index.html new file mode 100644 index 000000000..6e82c4126 --- /dev/null +++ b/api/basic_json/number_float_t/index.html @@ -0,0 +1,13 @@ + number_float_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::number_float_t

using number_float_t = NumberFloatType;
+

The type used to store JSON numbers (floating-point).

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.

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 is not enforced in C++. Instead, leading zeros in floating-point literals will be ignored. Internally, the value will be stored as 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 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/number_integer_t/index.html b/api/basic_json/number_integer_t/index.html new file mode 100644 index 000000000..cbe012c3b --- /dev/null +++ b/api/basic_json/number_integer_t/index.html @@ -0,0 +1,13 @@ + number_integer_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::number_integer_t

using number_integer_t = NumberIntegerType;
+

The type used to store JSON numbers (integers).

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.

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 is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 be automatically be stored as number_unsigned_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.

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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/number_unsigned_t/index.html b/api/basic_json/number_unsigned_t/index.html new file mode 100644 index 000000000..2b550aaa6 --- /dev/null +++ b/api/basic_json/number_unsigned_t/index.html @@ -0,0 +1,13 @@ + number_unsigned_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::number_unsigned_t

using number_unsigned_t = NumberUnsignedType;
+

The type used to store JSON numbers (unsigned).

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.

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 is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 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 be 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 \f[-2^{53}+1, 2^{53}-1]\f 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/object/index.html b/api/basic_json/object/index.html new file mode 100644 index 000000000..ecbd1537d --- /dev/null +++ b/api/basic_json/object/index.html @@ -0,0 +1,34 @@ + object - JSON for Modern C++
Skip to content

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 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 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 which 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/object_comparator_t/index.html b/api/basic_json/object_comparator_t/index.html new file mode 100644 index 000000000..04f78aea6 --- /dev/null +++ b/api/basic_json/object_comparator_t/index.html @@ -0,0 +1,17 @@ + object_comparator_t - JSON for Modern C++
Skip to content

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. Defined as typename object_t::key_compare if available, and default_object_comparator_t otherwise.

Examples

Example

The example below demonstrates the used object comparator.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/object_t/index.html b/api/basic_json/object_t/index.html new file mode 100644 index 000000000..67e3b664b --- /dev/null +++ b/api/basic_json/object_t/index.html @@ -0,0 +1,31 @@ + object_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::object_t

using object_t = ObjectType<StringType,
+                            basic_json,
+                            default_object_comparator_t,
+                            AllocatorType<std::pair<const StringType, basic_json>>>;
+

The type used to store JSON objects.

RFC 8259 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<StringType> 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<std::string>, // key_compare
+  std::allocator<std::pair<const std::string, basic_json>> // allocator_type
+>
+
+// since C++14
+std::map<
+  std::string, // key_type
+  basic_json, // value_type
+  std::less<>, // key_compare
+  std::allocator<std::pair<const std::string, basic_json>> // allocator_type
+>
+

See default_object_comparator_t 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) 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 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.

Object key order

The order 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, 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<json::string_t, json>.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator+=/index.html b/api/basic_json/operator+=/index.html new file mode 100644 index 000000000..4ac143316 --- /dev/null +++ b/api/basic_json/operator+=/index.html @@ -0,0 +1,99 @@ + operator+= - JSON for Modern C++
Skip to content

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.

  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&&).

Parameters

val (in)
the value to add to the JSON array/object
init (in)
an initializer list

Return value

*this

Exceptions

All functions can throw the following exception: - Throws type_error.308 when called on a type other than JSON array or null; example: "cannot use operator+=() 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<basic_json>, see #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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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]]
+

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator=/index.html b/api/basic_json/operator=/index.html new file mode 100644 index 000000000..34c476fa7 --- /dev/null +++ b/api/basic_json/operator=/index.html @@ -0,0 +1,27 @@ + operator= - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator=

basic_json& operator=(basic_json other) noexcept (
+    std::is_nothrow_move_constructible<value_t>::value &&
+    std::is_nothrow_move_assignable<value_t>::value &&
+    std::is_nothrow_move_constructible<json_value>::value &&
+    std::is_nothrow_move_assignable<json_value>::value
+);
+

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

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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
+

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator[]/index.html b/api/basic_json/operator[]/index.html new file mode 100644 index 000000000..191c55977 --- /dev/null +++ b/api/basic_json/operator[]/index.html @@ -0,0 +1,286 @@ + operator[] - JSON for Modern C++
Skip to content

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<typename KeyType>
+reference operator[](KeyType&& key);
+template<typename KeyType>
+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 typename object_t::key_type and 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 that is comparable with string_t using object_comparator_t. This can also be a string view (C++17).

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 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 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 if an array index in the passed JSON pointer ptr begins with '0'.
    • Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number.
    • Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr for the const version.
    • Throws out_of_range.404 if the JSON pointer ptr can not be resolved.

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

Undefined behavior and runtime assertions

  1. If the element with key 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!
  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.

  2. 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.

  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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <iomanip>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_ValueType/index.html b/api/basic_json/operator_ValueType/index.html new file mode 100644 index 000000000..4397577a9 --- /dev/null +++ b/api/basic_json/operator_ValueType/index.html @@ -0,0 +1,79 @@ + operator ValueType - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator ValueType

template<typename ValueType>
+JSON_EXPLICIT operator ValueType() const;
+

Implicit type conversion between the JSON value and a compatible value. The call is realized by calling get(). See 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<ValueType> 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<typename ValueType>
+operator ValueType() const;
+

If JSON_USE_IMPLICIT_CONVERSIONS is set to 0, JSON_EXPLICIT is defined to explicit:

template<typename ValueType>
+explicit operator ValueType() const;
+

That is, implicit conversions can be switched off by defining JSON_USE_IMPLICIT_CONVERSIONS 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 to 0 and replace any implicit conversions with calls to get.

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<short>, (3) A JSON object can be converted to C++ associative containers such as std::unordered_map<std::string, json>.

#include <iostream>
+#include <unordered_map>
+#include <nlohmann/json.hpp>
+
+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<short> v7 = json_types["array"];
+    std::unordered_map<std::string, json> 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 (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
+

Version history


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_eq/index.html b/api/basic_json/operator_eq/index.html new file mode 100644 index 000000000..e1663f863 --- /dev/null +++ b/api/basic_json/operator_eq/index.html @@ -0,0 +1,118 @@ + operator== - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator==

// until C++20
+bool operator==(const_reference lhs, const_reference rhs) noexcept;   // (1)
+
+template<typename ScalarType>
+bool operator==(const_reference lhs, const ScalarType rhs) noexcept;  // (2)
+
+template<typename ScalarType>
+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<typename ScalarType>
+    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, or (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<ScalarType>::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.
    2. Comparing a NaN with another NaN.
    3. 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 could be used, for instance

template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
+inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
+{
+    return std::abs(a - b) <= epsilon;
+}
+

Or you can self-defined 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<float>::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 or nlohmann::ordered_json is used:

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_ge/index.html b/api/basic_json/operator_ge/index.html new file mode 100644 index 000000000..59e51c486 --- /dev/null +++ b/api/basic_json/operator_ge/index.html @@ -0,0 +1,37 @@ + operator>= - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator>=

// until C++20
+bool operator>=(const_reference lhs, const_reference rhs) noexcept;   // (1)
+
+template<typename ScalarType>
+bool operator>=(const_reference lhs, const ScalarType rhs) noexcept;  // (2)
+
+template<typename ScalarType>
+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<).
  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<ScalarType>::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. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

Examples

Example

The example demonstrates comparing several JSON types.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_gt/index.html b/api/basic_json/operator_gt/index.html new file mode 100644 index 000000000..f04882edf --- /dev/null +++ b/api/basic_json/operator_gt/index.html @@ -0,0 +1,37 @@ + operator> - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator>

// until C++20
+bool operator>(const_reference lhs, const_reference rhs) noexcept;   // (1)
+
+template<typename ScalarType>
+bool operator>(const_reference lhs, const ScalarType rhs) noexcept;  // (2)
+
+template<typename ScalarType>
+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<=).
  2. Compares wether 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<ScalarType>::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. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

Examples

Example

The example demonstrates comparing several JSON types.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_gtgt/index.html b/api/basic_json/operator_gtgt/index.html new file mode 100644 index 000000000..751c3385e --- /dev/null +++ b/api/basic_json/operator_gtgt/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/api/basic_json/operator_le/index.html b/api/basic_json/operator_le/index.html new file mode 100644 index 000000000..a2584071d --- /dev/null +++ b/api/basic_json/operator_le/index.html @@ -0,0 +1,37 @@ + operator<= - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator<=

// until C++20
+bool operator<=(const_reference lhs, const_reference rhs) noexcept;   // (1)
+
+template<typename ScalarType>
+bool operator<=(const_reference lhs, const ScalarType rhs) noexcept;  // (2)
+
+template<typename ScalarType>
+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<).
  2. Compares wether 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<ScalarType>::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. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

Examples

Example

The example demonstrates comparing several JSON types.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_literal_json/index.html b/api/basic_json/operator_literal_json/index.html new file mode 100644 index 000000000..669f44308 --- /dev/null +++ b/api/basic_json/operator_literal_json/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/api/basic_json/operator_literal_json_pointer/index.html b/api/basic_json/operator_literal_json_pointer/index.html new file mode 100644 index 000000000..657da36ee --- /dev/null +++ b/api/basic_json/operator_literal_json_pointer/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/api/basic_json/operator_lt/index.html b/api/basic_json/operator_lt/index.html new file mode 100644 index 000000000..ca9c2108f --- /dev/null +++ b/api/basic_json/operator_lt/index.html @@ -0,0 +1,37 @@ + operator< - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator<

// until C++20
+bool operator<(const_reference lhs, const_reference rhs) noexcept;   // (1)
+
+template<typename ScalarType>
+bool operator<(const_reference lhs, const ScalarType rhs) noexcept;  // (2)
+
+template<typename ScalarType>
+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
      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 wether 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<ScalarType>::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. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Operator overload resolution

Since C++20 overload resolution will consider the rewritten candidate generated from operator<=>.

Examples

Example

The example demonstrates comparing several JSON types.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_ltlt/index.html b/api/basic_json/operator_ltlt/index.html new file mode 100644 index 000000000..806b11426 --- /dev/null +++ b/api/basic_json/operator_ltlt/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/api/basic_json/operator_ne/index.html b/api/basic_json/operator_ne/index.html new file mode 100644 index 000000000..e943aec62 --- /dev/null +++ b/api/basic_json/operator_ne/index.html @@ -0,0 +1,72 @@ + operator!= - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator!=

// until C++20
+bool operator!=(const_reference lhs, const_reference rhs) noexcept;   // (1)
+
+template<typename ScalarType>
+bool operator!=(const_reference lhs, const ScalarType rhs) noexcept;  // (2)
+
+template<typename ScalarType>
+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<typename ScalarType>
+    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).
  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<ScalarType>::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. 2. Comparing a NaN with another NaN. 3. Comparing a NaN and any other number.

Examples

Example

The example demonstrates comparing several JSON types.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.
  2. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_spaceship/index.html b/api/basic_json/operator_spaceship/index.html new file mode 100644 index 000000000..cb2188128 --- /dev/null +++ b/api/basic_json/operator_spaceship/index.html @@ -0,0 +1,98 @@ + operator - JSON for Modern C++
Skip to content

nlohmann::basic_json::operator<=>

// since C++20
+class basic_json {
+    std::partial_ordering operator<=>(const_reference rhs) const noexcept;  // (1)
+
+    template<typename ScalarType>
+    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).
  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<ScalarType>::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.
    2. Comparing a NaN with another NaN.
    3. Comparing a NaN and any other number.

Examples

Example: (1) comparing JSON values

The example demonstrates comparing several JSON values.

#include <compare>
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+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" <=> <discarded> := unordered
+
Example: (2) comparing JSON values and scalars

The example demonstrates comparing several JSON values and scalars.

#include <compare>
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+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<json::number_float_t>;
+    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

Version history

  1. Added in version 3.11.0.
  2. Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/operator_value_t/index.html b/api/basic_json/operator_value_t/index.html new file mode 100644 index 000000000..33635648a --- /dev/null +++ b/api/basic_json/operator_value_t/index.html @@ -0,0 +1,48 @@ + operator value_t - JSON for Modern C++
Skip to content

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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/other_error/index.html b/api/basic_json/other_error/index.html new file mode 100644 index 000000000..2b2cbd68f --- /dev/null +++ b/api/basic_json/other_error/index.html @@ -0,0 +1,34 @@ + other_error - JSON for Modern C++
Skip to content

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).

uml diagram

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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

Version history

  • Since version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/out_of_range/index.html b/api/basic_json/out_of_range/index.html new file mode 100644 index 000000000..6cbba03b9 --- /dev/null +++ b/api/basic_json/out_of_range/index.html @@ -0,0 +1,24 @@ + out_of_range - JSON for Modern C++
Skip to content

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 case of array indices or nonexisting object keys.

Exceptions have ids 4xx (see list of out-of-range errors).

uml diagram

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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    try
+    {
+        // calling at() for an invalid index
+        json j = {1, 2, 3, 4};
+        j.at(4) = 10;
+    }
+    catch (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

Version history

  • Since version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/parse/index.html b/api/basic_json/parse/index.html new file mode 100644 index 000000000..8242ec25c --- /dev/null +++ b/api/basic_json/parse/index.html @@ -0,0 +1,336 @@ + parse - JSON for Modern C++
Skip to content

nlohmann::basic_json::parse

// (1)
+template<typename InputType>
+static basic_json parse(InputType&& i,
+                        const parser_callback_t cb = nullptr,
+                        const bool allow_exceptions = true,
+                        const bool ignore_comments = false);
+
+// (2)
+template<typename IteratorType>
+static basic_json parse(IteratorType first, IteratorType last,
+                        const parser_callback_t cb = nullptr,
+                        const bool allow_exceptions = true,
+                        const bool ignore_comments = 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 (must not be null)
  • a C-style array of characters
  • a pointer to a null-terminated string of single byte characters
  • 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<std::uint8_t>::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 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)
first (in)
iterator to start of character range
last (in)
iterator to end of 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.

Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

Exceptions

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

(1) A UTF-8 byte order mark is silently ignored.

Runtime assertion

The precondition that a passed FILE pointer must not be null is enforced with a runtime assertion.

Examples

Parsing from a character array

The example below demonstrates the parse() function reading from an array.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // a JSON text given as std::vector
+    std::vector<std::uint8_t> 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // a JSON text given an input with other values
+    std::vector<std::uint8_t> 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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<U+000A>'
+the input is invalid JSON
+

See also

  • accept - check if the input is valid JSON
  • 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.

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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/parse_error/index.html b/api/basic_json/parse_error/index.html new file mode 100644 index 000000000..45a4ee9b2 --- /dev/null +++ b/api/basic_json/parse_error/index.html @@ -0,0 +1,25 @@ + parse_error - JSON for Modern C++
Skip to content

nlohmann::basic_json::parse_error

class parse_error : public exception;
+

This exception is thrown by the library 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).

uml diagram

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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    try
+    {
+        // parsing input with a syntax error
+        json::parse("[1,2,3,]");
+    }
+    catch (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

Version history

  • Since version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/parse_event_t/index.html b/api/basic_json/parse_event_t/index.html new file mode 100644 index 000000000..e052dd42b --- /dev/null +++ b/api/basic_json/parse_event_t/index.html @@ -0,0 +1,9 @@ + parse_event_t - JSON for Modern C++
Skip to content

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

Example when certain parse events are triggered

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/parser_callback_t/index.html b/api/basic_json/parser_callback_t/index.html new file mode 100644 index 000000000..2a8539aa7 --- /dev/null +++ b/api/basic_json/parser_callback_t/index.html @@ -0,0 +1,87 @@ + parser_callback_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::parser_callback_t

template<typename BasicJsonType>
+using parser_callback_t =
+    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
+

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.

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

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 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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
+    }
+}
+

Version history

  • Added in version 1.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/patch/index.html b/api/basic_json/patch/index.html new file mode 100644 index 000000000..53bcb030f --- /dev/null +++ b/api/basic_json/patch/index.html @@ -0,0 +1,46 @@ + patch - JSON for Modern C++
Skip to content

nlohmann::basic_json::patch

basic_json patch(const basic_json& json_patch) const;
+

JSON Patch 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 if the JSON patch does not consist of an array of objects.
  • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: "operation add must have member path".
  • Throws out_of_range.401 if an array index is out of range.
  • Throws out_of_range.403 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 if JSON pointer has no parent ("add", "remove", "move")
  • Throws out_of_range.501 if "test" operation was unsuccessful.

Complexity

Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is affected by the patch, 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/patch_inplace/index.html b/api/basic_json/patch_inplace/index.html new file mode 100644 index 000000000..dfdcaf88a --- /dev/null +++ b/api/basic_json/patch_inplace/index.html @@ -0,0 +1,50 @@ + patch_inplace - JSON for Modern C++
Skip to content

nlohmann::basic_json::patch_inplace

void patch_inplace(const basic_json& json_patch) const;
+

JSON Patch 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 if the JSON patch does not consist of an array of objects.
  • Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: "operation add must have member path".
  • Throws out_of_range.401 if an array index is out of range.
  • Throws out_of_range.403 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 if JSON pointer has no parent ("add", "remove", "move")
  • Throws out_of_range.501 if "test" operation was unsuccessful.

Complexity

Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is affected by the patch, the complexity can usually be neglected.

Notes

Unlike patch, 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/push_back/index.html b/api/basic_json/push_back/index.html new file mode 100644 index 000000000..e2025d404 --- /dev/null +++ b/api/basic_json/push_back/index.html @@ -0,0 +1,99 @@ + push_back - JSON for Modern C++
Skip to content

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.

  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&&).

Parameters

val (in)
the value to add to the JSON array/object
init (in)
an initializer list

Exceptions

All functions can throw the following exception: - Throws type_error.308 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<basic_json>, see #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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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]]
+

Version history

  1. Since version 1.0.0.
  2. Since version 1.0.0.
  3. Since version 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/rbegin/index.html b/api/basic_json/rbegin/index.html new file mode 100644 index 000000000..6a4782de2 --- /dev/null +++ b/api/basic_json/rbegin/index.html @@ -0,0 +1,20 @@ + rbegin - JSON for Modern C++
Skip to content

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.

Illustration from cppreference.com

Return value

reverse 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 rbegin().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/rend/index.html b/api/basic_json/rend/index.html new file mode 100644 index 000000000..4fc79c111 --- /dev/null +++ b/api/basic_json/rend/index.html @@ -0,0 +1,23 @@ + rend - JSON for Modern C++
Skip to content

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.

Illustration from cppreference.com

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 eend().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/sax_parse/index.html b/api/basic_json/sax_parse/index.html new file mode 100644 index 000000000..6679d74f5 --- /dev/null +++ b/api/basic_json/sax_parse/index.html @@ -0,0 +1,184 @@ + sax_parse - JSON for Modern C++
Skip to content

nlohmann::basic_json::sax_parse

// (1)
+template <typename InputType, typename SAX>
+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);
+
+// (2)
+template<class IteratorType, class SAX>
+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);
+

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 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.

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
Description
SAX
Description

Parameters

i (in)
Input to parse from.
sax (in)
SAX event listener
format (in)
the format to parse (JSON, CBOR, MessagePack, or UBJSON) (optional, input_format_t::json by default), see input_format_t 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)
first (in)
iterator to start of character range
last (in)
iterator to end of character range

Return value

return value of the last processed SAX event

Exception safety

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.
  • Ignoring comments via ignore_comments added in version 3.9.0.

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);.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/size/index.html b/api/basic_json/size/index.html new file mode 100644 index 000000000..5719c6857 --- /dev/null +++ b/api/basic_json/size/index.html @@ -0,0 +1,40 @@ + size - JSON for Modern C++
Skip to content

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 and object_t satisfy the 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/std_hash/index.html b/api/basic_json/std_hash/index.html new file mode 100644 index 000000000..f7ec20a08 --- /dev/null +++ b/api/basic_json/std_hash/index.html @@ -0,0 +1,31 @@ + std::hash<basic_json> - JSON for Modern C++
Skip to content

std::hash<nlohmann::basic_json>

namespace std {
+    struct hash<nlohmann::basic_json>;
+}
+

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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+using namespace nlohmann::literals;
+
+int main()
+{
+    std::cout << "hash(null) = " << std::hash<json> {}(json(nullptr)) << '\n'
+              << "hash(false) = " << std::hash<json> {}(json(false)) << '\n'
+              << "hash(0) = " << std::hash<json> {}(json(0)) << '\n'
+              << "hash(0U) = " << std::hash<json> {}(json(0U)) << '\n'
+              << "hash(\"\") = " << std::hash<json> {}(json("")) << '\n'
+              << "hash({}) = " << std::hash<json> {}(json::object()) << '\n'
+              << "hash([]) = " << std::hash<json> {}(json::array()) << '\n'
+              << "hash({\"hello\": \"world\"}) = " << std::hash<json> {}("{\"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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/std_swap/index.html b/api/basic_json/std_swap/index.html new file mode 100644 index 000000000..fccd24bf7 --- /dev/null +++ b/api/basic_json/std_swap/index.html @@ -0,0 +1,29 @@ + std::swap<basic_json> - JSON for Modern C++
Skip to content

std::swap<basic_json>

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

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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 1.0.0.
  • Extended for arbitrary basic_json types in version 3.10.5.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/string_t/index.html b/api/basic_json/string_t/index.html new file mode 100644 index 000000000..01335d098 --- /dev/null +++ b/api/basic_json/string_t/index.html @@ -0,0 +1,13 @@ + string_t - JSON for Modern C++
Skip to content

nlohmann::basic_json::string_t

using string_t = StringType;
+

The type used to store JSON strings.

RFC 8259 describes JSON strings as follows:

A string is a sequence of zero or more Unicode characters.

To store objects 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.

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 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/swap/index.html b/api/basic_json/swap/index.html new file mode 100644 index 000000000..8c3951c16 --- /dev/null +++ b/api/basic_json/swap/index.html @@ -0,0 +1,129 @@ + swap - JSON for Modern C++
Skip to content

nlohmann::basic_json::swap

// (1)
+void swap(reference other) noexcept;
+
+// (2)
+void swap(reference left, reference right) noexcept;
+
+// (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 if called on JSON values other than arrays; example: "cannot use swap() with boolean"
  4. Throws type_error.310 if called on JSON values other than objects; example: "cannot use swap() with boolean"
  5. Throws type_error.310 if called on JSON values other than strings; example: "cannot use swap() with boolean"
  6. Throws type_error.310 if called on JSON values other than binaries; example: "cannot use swap() with boolean"
  7. Throws type_error.310 if called on JSON values other than binaries; example: "cannot use swap() with boolean"

Complexity

Constant.

Examples

Example: Swap JSON value (1, 2)

The example below shows how JSON values can be swapped with swap().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 string (6)

The example below shows how binary values can be swapped with swap().

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/to_bjdata/index.html b/api/basic_json/to_bjdata/index.html new file mode 100644 index 000000000..862252dca --- /dev/null +++ b/api/basic_json/to_bjdata/index.html @@ -0,0 +1,79 @@ + to_bjdata - JSON for Modern C++
Skip to content

nlohmann::basic_json::to_bjdata

// (1)
+static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
+                                           const bool use_size = false,
+                                           const bool use_type = false);
+
+// (2)
+static void to_bjdata(const basic_json& j, detail::output_adapter<std::uint8_t> o,
+                      const bool use_size = false, const bool use_type = false);
+static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
+                      const bool use_size = false, const bool use_type = false);
+

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 is described on a dedicated page.

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. 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.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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<std::uint8_t> 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<std::uint8_t> v_array = json::to_bjdata(array);
+    // serialize it to BJData using size optimization
+    std::vector<std::uint8_t> v_array_size = json::to_bjdata(array, true);
+    // serialize it to BJData using type optimization
+    std::vector<std::uint8_t> 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
+

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/to_bson/index.html b/api/basic_json/to_bson/index.html new file mode 100644 index 000000000..d26b6c65a --- /dev/null +++ b/api/basic_json/to_bson/index.html @@ -0,0 +1,30 @@ + to_bson - JSON for Modern C++
Skip to content

nlohmann::basic_json::to_bson

// (1)
+static std::vector<std::uint8_t> to_bson(const basic_json& j);
+
+// (2)
+static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o);
+static void to_bson(const basic_json& j, detail::output_adapter<char> 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 is described on a dedicated page.

Parameters

j (in)
JSON value to serialize
o (in)
output adapter to write serialization to

Return value

  1. BSON 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 BSON format.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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<std::uint8_t> 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 
+

Version history

  • Added in version 3.4.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/to_cbor/index.html b/api/basic_json/to_cbor/index.html new file mode 100644 index 000000000..3ae64d114 --- /dev/null +++ b/api/basic_json/to_cbor/index.html @@ -0,0 +1,30 @@ + to_cbor - JSON for Modern C++
Skip to content

nlohmann::basic_json::to_cbor

// (1)
+static std::vector<std::uint8_t> to_cbor(const basic_json& j);
+
+// (2)
+static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o);
+static void to_cbor(const basic_json& j, detail::output_adapter<char> 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 which 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 is described on a dedicated page.

Parameters

j (in)
JSON value to serialize
o (in)
output adapter to write serialization to

Return value

  1. CBOR 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 CBOR format.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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<std::uint8_t> 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 
+

Version history

  • Added in version 2.0.9.
  • Compact representation of floating-point numbers added in version 3.8.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/to_msgpack/index.html b/api/basic_json/to_msgpack/index.html new file mode 100644 index 000000000..c65256ac0 --- /dev/null +++ b/api/basic_json/to_msgpack/index.html @@ -0,0 +1,30 @@ + to_msgpack - JSON for Modern C++
Skip to content

nlohmann::basic_json::to_msgpack

// (1)
+static std::vector<std::uint8_t> to_msgpack(const basic_json& j);
+
+// (2)
+static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o);
+static void to_msgpack(const basic_json& j, detail::output_adapter<char> o);
+

Serializes a given JSON value j to a byte vector using the MessagePack serialization format. MessagePack is a binary serialization format which 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 is described on a dedicated page.

Parameters

j (in)
JSON value to serialize
o (in)
output adapter to write serialization to

Return value

  1. MessagePack 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 MessagePack format.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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<std::uint8_t> 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 
+

Version history

  • Added in version 2.0.9.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/to_string/index.html b/api/basic_json/to_string/index.html new file mode 100644 index 000000000..42c7b664d --- /dev/null +++ b/api/basic_json/to_string/index.html @@ -0,0 +1,31 @@ + to_string - JSON for Modern C++
Skip to content

to_string(basic_json)

template <typename BasicJsonType>
+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

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 if a string stored inside the JSON value is not UTF-8 encoded

Complexity

Linear.

Possible implementation

template <typename BasicJsonType>
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

Added in version 3.7.0.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/to_ubjson/index.html b/api/basic_json/to_ubjson/index.html new file mode 100644 index 000000000..7c8c11863 --- /dev/null +++ b/api/basic_json/to_ubjson/index.html @@ -0,0 +1,79 @@ + to_ubjson - JSON for Modern C++
Skip to content

nlohmann::basic_json::to_ubjson

// (1)
+static std::vector<std::uint8_t> 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<std::uint8_t> o,
+                      const bool use_size = false, const bool use_type = false);
+static void to_ubjson(const basic_json& j, detail::output_adapter<char> 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 is described on a dedicated page.

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 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.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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<std::uint8_t> 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<std::uint8_t> v_array = json::to_ubjson(array);
+    // serialize it to UBJSON using size optimization
+    std::vector<std::uint8_t> v_array_size = json::to_ubjson(array, true);
+    // serialize it to UBJSON using type optimization
+    std::vector<std::uint8_t> 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
+

Version history

  • Added in version 3.1.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/type/index.html b/api/basic_json/type/index.html new file mode 100644 index 000000000..da29e3a19 --- /dev/null +++ b/api/basic_json/type/index.html @@ -0,0 +1,38 @@ + type - JSON for Modern C++
Skip to content

nlohmann::basic_json::type

constexpr value_t type() const noexcept;
+

Return the type of the JSON value as a value from the value_t 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/type_error/index.html b/api/basic_json/type_error/index.html new file mode 100644 index 000000000..410b6c7d9 --- /dev/null +++ b/api/basic_json/type_error/index.html @@ -0,0 +1,24 @@ + type_error - JSON for Modern C++
Skip to content

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).

uml diagram

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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    try
+    {
+        // calling push_back() on a string value
+        json j = "string";
+        j.push_back("another string");
+    }
+    catch (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

Version history

  • Since version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/type_name/index.html b/api/basic_json/type_name/index.html new file mode 100644 index 000000000..531dd8788 --- /dev/null +++ b/api/basic_json/type_name/index.html @@ -0,0 +1,37 @@ + type_name - JSON for Modern C++
Skip to content

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):

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/unflatten/index.html b/api/basic_json/unflatten/index.html new file mode 100644 index 000000000..b9f3747d0 --- /dev/null +++ b/api/basic_json/unflatten/index.html @@ -0,0 +1,46 @@ + unflatten - JSON for Modern C++
Skip to content

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() 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)
  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:

Complexity

Linear in the size the JSON value.

Notes

Empty objects and arrays are flattened by flatten() to null values and can not 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 2.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/update/index.html b/api/basic_json/update/index.html new file mode 100644 index 000000000..b08a54005 --- /dev/null +++ b/api/basic_json/update/index.html @@ -0,0 +1,113 @@ + update - JSON for Modern C++
Skip to content

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.
  2. 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.

The function is motivated by Python's dict.update function.

Parameters

j (in)
JSON object to read values from
merge_objects (in)
when true, existing keys are not overwritten, but contents of objects are merged recursively (default: false)
first (in)
begin of the range of elements to insert
last (in)
end of the range of elements to insert

Exceptions

  1. The function can throw the following exceptions:
    • Throws type_error.312 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 if called on JSON values other than objects; example: "cannot use update() with string"
    • Throws invalid_iterator.202 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 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.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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"}
+}
+

Version history

  • Added in version 3.0.0.
  • Added merge_objects parameter in 3.10.4.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/value/index.html b/api/basic_json/value/index.html new file mode 100644 index 000000000..b5fb4c444 --- /dev/null +++ b/api/basic_json/value/index.html @@ -0,0 +1,121 @@ + value - JSON for Modern C++
Skip to content

nlohmann::basic_json::value

// (1)
+template<class ValueType>
+ValueType value(const typename object_t::key_type& key,
+                ValueType&& default_value) const;
+
+// (2)
+template<class ValueType, class KeyType>
+ValueType value(KeyType&& key,
+                ValueType&& default_value) const;
+
+// (3)
+template<class ValueType>
+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;
    +}
    +

  2. 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.

  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

    try {
    +   return at(ptr);
    +} catch(out_of_range) {
    +   return default_value;
    +}
    +

Differences to at and operator[]

  • Unlike at, this function does not throw if the given key/ptr was not found.
  • Unlike operator[], 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 that is comparable with string_t using object_comparator_t. 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
  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 if default_value does not match the type of the value at key
    • Throws type_error.306 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 if default_value does not match the type of the value at ptr
    • Throws type_error.306 if the JSON value is not an object; in that case, using value() with a key makes no sense.

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.

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <string_view>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/value_t/index.html b/api/basic_json/value_t/index.html new file mode 100644 index 000000000..faf067ce1 --- /dev/null +++ b/api/basic_json/value_t/index.html @@ -0,0 +1,49 @@ + value_t - JSON for Modern C++
Skip to content

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, is_object, is_array, is_string, is_boolean, is_number (with is_number_integer, is_number_unsigned, and is_number_float), is_discarded, is_binary, is_primitive, and is_structured rely on it.

Notes

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.

Types of numbers

There are three enumerators for numbers (number_integer, number_unsigned, and number_float) to distinguish between different types of numbers:

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/basic_json/~basic_json/index.html b/api/basic_json/~basic_json/index.html new file mode 100644 index 000000000..6c8e70daa --- /dev/null +++ b/api/basic_json/~basic_json/index.html @@ -0,0 +1,2 @@ + (Destructor) - JSON for Modern C++
Skip to content

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.

Last update: March 8, 2023
\ No newline at end of file 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 new file mode 100644 index 000000000..cf68697b6 --- /dev/null +++ b/api/byte_container_with_subtype/byte_container_with_subtype/index.html @@ -0,0 +1,37 @@ + (constructor) - JSON for Modern C++
Skip to content

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 empty binary container without subtype.
  2. Create binary container without subtype.
  3. Create binary container with subtype.

Parameters

container (in)
binary container
subtype (in)
subtype

Examples

Example

The example below demonstrates how byte containers can be created.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+// define a byte container based on std::vector
+using byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;
+
+using json = nlohmann::json;
+
+int main()
+{
+    // (1) create empty container
+    auto c1 = byte_container_with_subtype();
+
+    std::vector<std::uint8_t> 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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/byte_container_with_subtype/clear_subtype/index.html b/api/byte_container_with_subtype/clear_subtype/index.html new file mode 100644 index 000000000..d411b0af2 --- /dev/null +++ b/api/byte_container_with_subtype/clear_subtype/index.html @@ -0,0 +1,25 @@ + clear_subtype - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+// define a byte container based on std::vector
+using byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;
+
+using json = nlohmann::json;
+
+int main()
+{
+    std::vector<std::uint8_t> 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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/byte_container_with_subtype/has_subtype/index.html b/api/byte_container_with_subtype/has_subtype/index.html new file mode 100644 index 000000000..aaa6dbfb3 --- /dev/null +++ b/api/byte_container_with_subtype/has_subtype/index.html @@ -0,0 +1,23 @@ + has_subtype - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+// define a byte container based on std::vector
+using byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;
+
+int main()
+{
+    std::vector<std::uint8_t> 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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/byte_container_with_subtype/index.html b/api/byte_container_with_subtype/index.html new file mode 100644 index 000000000..6fd55c14b --- /dev/null +++ b/api/byte_container_with_subtype/index.html @@ -0,0 +1,3 @@ + Overview - JSON for Modern C++
Skip to content

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 type of subtypes to std::uint64_t in 3.10.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/byte_container_with_subtype/set_subtype/index.html b/api/byte_container_with_subtype/set_subtype/index.html new file mode 100644 index 000000000..841381bb3 --- /dev/null +++ b/api/byte_container_with_subtype/set_subtype/index.html @@ -0,0 +1,26 @@ + set_subtype - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+// define a byte container based on std::vector
+using byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;
+
+using json = nlohmann::json;
+
+int main()
+{
+    std::vector<std::uint8_t> 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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/byte_container_with_subtype/subtype/index.html b/api/byte_container_with_subtype/subtype/index.html new file mode 100644 index 000000000..772b17d1e --- /dev/null +++ b/api/byte_container_with_subtype/subtype/index.html @@ -0,0 +1,26 @@ + subtype - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+// define a byte container based on std::vector
+using byte_container_with_subtype = nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>;
+
+int main()
+{
+    std::vector<std::uint8_t> 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<byte_container_with_subtype::subtype_type>(-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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json/index.html b/api/json/index.html new file mode 100644 index 000000000..11bfaa3c2 --- /dev/null +++ b/api/json/index.html @@ -0,0 +1,68 @@ + json - JSON for Modern C++
Skip to content

nlohmann::json

using json = basic_json<>;
+

This type is the default specialization of the basic_json class which uses the standard template types.

Examples

Example

The example below demonstrates how to use the type nlohmann::json.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/back/index.html b/api/json_pointer/back/index.html new file mode 100644 index 000000000..2c292baa3 --- /dev/null +++ b/api/json_pointer/back/index.html @@ -0,0 +1,19 @@ + back - JSON for Modern C++
Skip to content

nlohmann::json_pointer::back

const string_t& back() const;
+

Return last reference token.

Return value

Last reference token.

Exceptions

Throws out_of_range.405 if JSON pointer has no parent.

Complexity

Constant.

Examples

Example

The example shows the usage of back.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/empty/index.html b/api/json_pointer/empty/index.html new file mode 100644 index 000000000..1979bde5c --- /dev/null +++ b/api/json_pointer/empty/index.html @@ -0,0 +1,26 @@ + empty - JSON for Modern C++
Skip to content

nlohmann::json_pointer::empty

bool empty() const noexcept;
+

Return whether 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/index.html b/api/json_pointer/index.html new file mode 100644 index 000000000..40ffb732e --- /dev/null +++ b/api/json_pointer/index.html @@ -0,0 +1,3 @@ + Overview - JSON for Modern C++
Skip to content

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

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/json_pointer/index.html b/api/json_pointer/json_pointer/index.html new file mode 100644 index 000000000..ec16df09b --- /dev/null +++ b/api/json_pointer/json_pointer/index.html @@ -0,0 +1,52 @@ + (Constructor) - JSON for Modern C++
Skip to content

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.

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 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
  • Throws parse_error.108 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 (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 (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 (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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/operator_eq/index.html b/api/json_pointer/operator_eq/index.html new file mode 100644 index 000000000..6e2bac635 --- /dev/null +++ b/api/json_pointer/operator_eq/index.html @@ -0,0 +1,85 @@ + operator== - JSON for Modern C++
Skip to content

nlohmann::json_pointer::operator==

// until C++20
+template<typename RefStringTypeLhs, typename RefStringTypeRhs>
+bool operator==(
+    const json_pointer<RefStringTypeLhs>& lhs,
+    const json_pointer<RefStringTypeRhs>& rhs) noexcept;            // (1)
+
+template<typename RefStringTypeLhs, typename StringType>
+bool operator==(
+    const json_pointer<RefStringTypeLhs>& lhs,
+    const StringType& rhs);                                         // (2)
+
+template<typename RefStringTypeRhs, typename StringType>
+bool operator==(
+    const StringType& lhs,
+    const json_pointer<RefStringTypeRhs>& rhs);                     // (2)
+
+// since C++20
+class json_pointer {
+    template<typename RefStringTypeRhs>
+    bool operator==(
+        const json_pointer<RefStringTypeRhs>& 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)

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:
  3. Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
  4. Throws parse_error.108 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <exception>
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.
  2. Added for backward compatibility and deprecated in version 3.11.2.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/operator_ne/index.html b/api/json_pointer/operator_ne/index.html new file mode 100644 index 000000000..c931ff044 --- /dev/null +++ b/api/json_pointer/operator_ne/index.html @@ -0,0 +1,75 @@ + operator!= - JSON for Modern C++
Skip to content

nlohmann::json_pointer::operator!=

// until C++20
+template<typename RefStringTypeLhs, typename RefStringTypeRhs>
+bool operator!=(
+    const json_pointer<RefStringTypeLhs>& lhs,
+    const json_pointer<RefStringTypeRhs>& rhs) noexcept;  // (1)
+
+template<typename RefStringTypeLhs, typename StringType>
+bool operator!=(
+    const json_pointer<RefStringTypeLhs>& lhs,
+    const StringType& rhs);                               // (2)
+
+template<typename RefStringTypeRhs, typename StringType>
+bool operator!=(
+    const StringType& lhs,
+    const json_pointer<RefStringTypeRhs>& 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)

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:
  3. Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash (/); see example below.
  4. Throws parse_error.108 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==.

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.
  2. Added for backward compatibility and deprecated in version 3.11.2.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/operator_slash/index.html b/api/json_pointer/operator_slash/index.html new file mode 100644 index 000000000..52739e7e9 --- /dev/null +++ b/api/json_pointer/operator_slash/index.html @@ -0,0 +1,31 @@ + operator/ - JSON for Modern C++
Skip to content

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
  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/.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.
  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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/operator_slasheq/index.html b/api/json_pointer/operator_slasheq/index.html new file mode 100644 index 000000000..e8160baa7 --- /dev/null +++ b/api/json_pointer/operator_slasheq/index.html @@ -0,0 +1,36 @@ + operator/= - JSON for Modern C++
Skip to content

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
  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/=.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.
  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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/operator_string/index.html b/api/json_pointer/operator_string/index.html new file mode 100644 index 000000000..d94837f26 --- /dev/null +++ b/api/json_pointer/operator_string/index.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/api/json_pointer/operator_string_t/index.html b/api/json_pointer/operator_string_t/index.html new file mode 100644 index 000000000..c27182594 --- /dev/null +++ b/api/json_pointer/operator_string_t/index.html @@ -0,0 +1,27 @@ + operator string_t - JSON for Modern C++
Skip to content

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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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
+

Version history

  • Since version 2.0.0.
  • Changed type to string_t and deprecated in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/parent_pointer/index.html b/api/json_pointer/parent_pointer/index.html new file mode 100644 index 000000000..eeb485805 --- /dev/null +++ b/api/json_pointer/parent_pointer/index.html @@ -0,0 +1,23 @@ + parent_pointer - JSON for Modern C++
Skip to content

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.

Complexity

Linear in the length of the JSON pointer.

Examples

Example

The example shows the result of parent_pointer for different JSON Pointers.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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"
+

Version history

Added in version 3.6.0.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/pop_back/index.html b/api/json_pointer/pop_back/index.html new file mode 100644 index 000000000..78e30717f --- /dev/null +++ b/api/json_pointer/pop_back/index.html @@ -0,0 +1,27 @@ + pop_back - JSON for Modern C++
Skip to content

nlohmann::json_pointer::pop_back

void pop_back();
+

Remove last reference token.

Exceptions

Throws out_of_range.405 if JSON pointer has no parent.

Complexity

Constant.

Examples

Example

The example shows the usage of pop_back.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/push_back/index.html b/api/json_pointer/push_back/index.html new file mode 100644 index 000000000..40d592516 --- /dev/null +++ b/api/json_pointer/push_back/index.html @@ -0,0 +1,29 @@ + push_back - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/string_t/index.html b/api/json_pointer/string_t/index.html new file mode 100644 index 000000000..a1bfab6ce --- /dev/null +++ b/api/json_pointer/string_t/index.html @@ -0,0 +1,17 @@ + string_t - JSON for Modern C++
Skip to content

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 for more information.

Examples

Example

The example shows the type string_t and its relation to basic_json::string_t.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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<json::json_pointer::string_t, json::string_t>::value << std::endl;
+}
+

Output:

This is a string.
+true
+

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_pointer/to_string/index.html b/api/json_pointer/to_string/index.html new file mode 100644 index 000000000..c9450525b --- /dev/null +++ b/api/json_pointer/to_string/index.html @@ -0,0 +1,49 @@ + to_string - JSON for Modern C++
Skip to content

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/binary/index.html b/api/json_sax/binary/index.html new file mode 100644 index 000000000..13accd254 --- /dev/null +++ b/api/json_sax/binary/index.html @@ -0,0 +1,119 @@ + binary - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<std::uint8_t> 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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/boolean/index.html b/api/json_sax/boolean/index.html new file mode 100644 index 000000000..2cae0e533 --- /dev/null +++ b/api/json_sax/boolean/index.html @@ -0,0 +1,170 @@ + boolean - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/end_array/index.html b/api/json_sax/end_array/index.html new file mode 100644 index 000000000..1bd171b09 --- /dev/null +++ b/api/json_sax/end_array/index.html @@ -0,0 +1,170 @@ + end_array - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/end_object/index.html b/api/json_sax/end_object/index.html new file mode 100644 index 000000000..6949732a2 --- /dev/null +++ b/api/json_sax/end_object/index.html @@ -0,0 +1,170 @@ + end_object - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/index.html b/api/json_sax/index.html new file mode 100644 index 000000000..07e06bb1f --- /dev/null +++ b/api/json_sax/index.html @@ -0,0 +1,3 @@ + Overview - JSON for Modern C++
Skip to content

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/key/index.html b/api/json_sax/key/index.html new file mode 100644 index 000000000..53ad61cec --- /dev/null +++ b/api/json_sax/key/index.html @@ -0,0 +1,170 @@ + key - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/null/index.html b/api/json_sax/null/index.html new file mode 100644 index 000000000..2ff60ec48 --- /dev/null +++ b/api/json_sax/null/index.html @@ -0,0 +1,170 @@ + null - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/number_float/index.html b/api/json_sax/number_float/index.html new file mode 100644 index 000000000..59f582e10 --- /dev/null +++ b/api/json_sax/number_float/index.html @@ -0,0 +1,170 @@ + number_float - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/number_integer/index.html b/api/json_sax/number_integer/index.html new file mode 100644 index 000000000..146fce1c7 --- /dev/null +++ b/api/json_sax/number_integer/index.html @@ -0,0 +1,170 @@ + number_integer - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/number_unsigned/index.html b/api/json_sax/number_unsigned/index.html new file mode 100644 index 000000000..55824c726 --- /dev/null +++ b/api/json_sax/number_unsigned/index.html @@ -0,0 +1,170 @@ + number_unsigned - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/parse_error/index.html b/api/json_sax/parse_error/index.html new file mode 100644 index 000000000..d803be9b9 --- /dev/null +++ b/api/json_sax/parse_error/index.html @@ -0,0 +1,172 @@ + parse_error - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/start_array/index.html b/api/json_sax/start_array/index.html new file mode 100644 index 000000000..12b8e7130 --- /dev/null +++ b/api/json_sax/start_array/index.html @@ -0,0 +1,170 @@ + start_array - JSON for Modern C++
Skip to content

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 object elements or -1 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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/start_object/index.html b/api/json_sax/start_object/index.html new file mode 100644 index 000000000..cbba53d06 --- /dev/null +++ b/api/json_sax/start_object/index.html @@ -0,0 +1,170 @@ + start_object - JSON for Modern C++
Skip to content

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 -1 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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/json_sax/string/index.html b/api/json_sax/string/index.html new file mode 100644 index 000000000..f0db13366 --- /dev/null +++ b/api/json_sax/string/index.html @@ -0,0 +1,170 @@ + string - JSON for Modern C++
Skip to content

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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<std::string> 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<U+000A>        }<U+000A>    }],
+            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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/index.html b/api/macros/index.html new file mode 100644 index 000000000..2ff6dfff1 --- /dev/null +++ b/api/macros/index.html @@ -0,0 +1 @@ + Overview - JSON for Modern C++
Skip to content

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


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_assert/index.html b/api/macros/json_assert/index.html new file mode 100644 index 000000000..dfa4334c5 --- /dev/null +++ b/api/macros/json_assert/index.html @@ -0,0 +1,27 @@ + JSON_ASSERT - JSON for Modern C++
Skip to content

JSON_ASSERT

#define JSON_ASSERT(x) /* value */
+

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

Parameters

x (in)
expression of scalar type

Default definition

The default value is assert(x).

#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[] with a missing object key on a const object). See page runtime assertions 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 <nlohmann/json.hpp>
+
+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 <cstdio>
+#include <cstdlib>
+#define JSON_ASSERT(x) if(!(x)){fprintf(stderr, "assertion error in %s\n", __FUNCTION__); std::abort();}
+
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    const json j = {{"key", "value"}};
+    auto v = j["missing"];
+}
+

Output:

assertion error in operator[]
+

Version history

  • Added in version 3.9.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_diagnostics/index.html b/api/macros/json_diagnostics/index.html new file mode 100644 index 000000000..a776aa1d9 --- /dev/null +++ b/api/macros/json_diagnostics/index.html @@ -0,0 +1,47 @@ + JSON_DIAGNOSTICS - JSON for Modern C++
Skip to content

JSON_DIAGNOSTICS

#define JSON_DIAGNOSTICS /* value */
+

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. 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 (OFF by default) which defines JSON_DIAGNOSTICS accordingly.

Examples

Example 1: default behavior
#include <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    json j;
+    j["address"]["street"] = "Fake Street";
+    j["address"]["housenumber"] = "12";
+
+    try
+    {
+        int housenumber = j["address"]["housenumber"];
+    }
+    catch (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 <iostream>
+
+# define JSON_DIAGNOSTICS 1
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    json j;
+    j["address"]["street"] = "Fake Street";
+    j["address"]["housenumber"] = "12";
+
+    try
+    {
+        int housenumber = j["address"]["housenumber"];
+    }
+    catch (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.

Version history

  • Added in version 3.10.0.
  • As of version 3.11.0 the definition is allowed to vary between translation units.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_disable_enum_serialization/index.html b/api/macros/json_disable_enum_serialization/index.html new file mode 100644 index 000000000..9e2de1d78 --- /dev/null +++ b/api/macros/json_disable_enum_serialization/index.html @@ -0,0 +1,92 @@ + JSON_DISABLE_ENUM_SERIALIZATION - JSON for Modern C++
Skip to content

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 (see arbitrary type conversions 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 (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 <nlohmann/json.hpp>
+
+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<Choice>();
+}
+
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 to parse and serialize the enum.

#define JSON_DISABLE_ENUM_SERIALIZATION 1
+#include <nlohmann/json.hpp>
+
+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<Choice>();
+}
+
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 <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+enum class Choice
+{
+    first,
+    second,
+};
+
+void from_json(const json& j, Choice& ch)
+{
+    auto value = j.get<std::string>();
+    if (value == "first")
+    {
+        ch = Choice::first;
+    }
+    else if (value == "second")
+    {
+        ch = Choice::second;
+    }
+}
+
+void to_json(json& j, const Choice& ch)
+{
+    auto value = j.get<std::string>();
+    if (value == "first")
+    {
+        ch = Choice::first;
+    }
+    else if (value == "second")
+    {
+        ch = Choice::second;
+    }
+}
+
+int main()
+{
+    // uses user-defined to_json function
+    const json j = Choice::first; 
+
+    // uses user-defined from_json function
+    Choice ch = j.get<Choice>();
+}
+

See also

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_has_cpp_11/index.html b/api/macros/json_has_cpp_11/index.html new file mode 100644 index 000000000..3a1fe652a --- /dev/null +++ b/api/macros/json_has_cpp_11/index.html @@ -0,0 +1,9 @@ + JSON_HAS_CPP_20 - JSON for Modern C++
Skip to content

JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20

#define JSON_HAS_CPP_11
+#define JSON_HAS_CPP_14
+#define JSON_HAS_CPP_17
+#define JSON_HAS_CPP_20
+

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

  • JSON_HAS_CPP_11 is always defined.
  • 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 <nlohmann/json.hpp>
+
+...
+

Version history

  • Added in version 3.10.5.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_has_filesystem/index.html b/api/macros/json_has_filesystem/index.html new file mode 100644 index 000000000..bb721ae66 --- /dev/null +++ b/api/macros/json_has_filesystem/index.html @@ -0,0 +1,7 @@ + JSON_HAS_FILESYSTEM - JSON for Modern C++
Skip to content

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. 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.

Default definition

The default value is detected based on the preprocessor macros __cpp_lib_filesystem, __cpp_lib_experimental_filesystem, __has_include(<filesystem>), or __has_include(<experimental/filesystem>).

Notes

  • Note that older compilers or older versions of libstd++ 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 <experimental/filesystem>.

#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
+#include <nlohmann/json.hpp>
+
+...
+

Version history

  • Added in version 3.10.5.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_has_ranges/index.html b/api/macros/json_has_ranges/index.html new file mode 100644 index 000000000..ad8ce41e1 --- /dev/null +++ b/api/macros/json_has_ranges/index.html @@ -0,0 +1,6 @@ + JSON_HAS_RANGES - JSON for Modern C++
Skip to content

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 <nlohmann/json.hpp>
+
+...
+

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_has_three_way_comparison/index.html b/api/macros/json_has_three_way_comparison/index.html new file mode 100644 index 000000000..7641ffadf --- /dev/null +++ b/api/macros/json_has_three_way_comparison/index.html @@ -0,0 +1,6 @@ + JSON_HAS_THREE_WAY_COMPARISON - JSON for Modern C++
Skip to content

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 <nlohmann/json.hpp>
+
+...
+

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_no_io/index.html b/api/macros/json_no_io/index.html new file mode 100644 index 000000000..0cb9817c4 --- /dev/null +++ b/api/macros/json_no_io/index.html @@ -0,0 +1,7 @@ + JSON_NO_IO - JSON for Modern C++
Skip to content

JSON_NO_IO

#define 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 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 <cstdio>, <ios>, <iosfwd>, <istream>, and <ostream>.

#define JSON_NO_IO 1
+#include <nlohmann/json.hpp>
+
+...
+

Version history

  • Added in version 3.10.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_noexception/index.html b/api/macros/json_noexception/index.html new file mode 100644 index 000000000..731d714a3 --- /dev/null +++ b/api/macros/json_noexception/index.html @@ -0,0 +1,7 @@ + JSON_NOEXCEPTION - JSON for Modern C++
Skip to content

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() string of exceptions is not available for MSVC if exceptions are disabled, see #2824.

Examples

Example

The code below switches off exceptions in the library.

#define JSON_NOEXCEPTION 1
+#include <nlohmann/json.hpp>
+
+...
+

See also

Version history

Added in version 2.1.0.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_skip_library_version_check/index.html b/api/macros/json_skip_library_version_check/index.html new file mode 100644 index 000000000..82b06db9a --- /dev/null +++ b/api/macros/json_skip_library_version_check/index.html @@ -0,0 +1,4 @@ + JSON_SKIP_LIBRARY_VERSION_CHECK - JSON for Modern C++
Skip to content

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 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.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_skip_unsupported_compiler_check/index.html b/api/macros/json_skip_unsupported_compiler_check/index.html new file mode 100644 index 000000000..7168cf43a --- /dev/null +++ b/api/macros/json_skip_unsupported_compiler_check/index.html @@ -0,0 +1,7 @@ + JSON_SKIP_UNSUPPORTED_COMPILER_CHECK - JSON for Modern C++
Skip to content

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 to use 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 <nlohmann/json.hpp>
+
+...
+

Version history

Added in version 3.2.0.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_throw_user/index.html b/api/macros/json_throw_user/index.html new file mode 100644 index 000000000..9a58d2b6e --- /dev/null +++ b/api/macros/json_throw_user/index.html @@ -0,0 +1,24 @@ + JSON_TRY_USER - JSON for Modern C++
Skip to content

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 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 exceptions. The macro is always followed by a scope.
  2. 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.
  3. 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 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 <iostream>
+
+#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 <nlohmann/json.hpp>
+

See also

Version history

  • Added in version 3.1.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_use_global_udls/index.html b/api/macros/json_use_global_udls/index.html new file mode 100644 index 000000000..d16d86191 --- /dev/null +++ b/api/macros/json_use_global_udls/index.html @@ -0,0 +1,32 @@ + JSON_USE_GLOBAL_UDLS - JSON for Modern C++
Skip to content

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 for details.

CMake option

The placement of user-defined string literals can also be controlled with the CMake option 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 <nlohmann/json.hpp>
+
+#include <iostream>
+
+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 <nlohmann/json.hpp>
+
+#include <iostream>
+
+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

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_use_implicit_conversions/index.html b/api/macros/json_use_implicit_conversions/index.html new file mode 100644 index 000000000..e7025ec7c --- /dev/null +++ b/api/macros/json_use_implicit_conversions/index.html @@ -0,0 +1,7 @@ + JSON_USE_IMPLICIT_CONVERSIONS - JSON for Modern C++
Skip to content

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.

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.

CMake option

Implicit conversions can also be controlled with the CMake option 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<std::string>();
+

See also

Version history

  • Added in version 3.9.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/json_use_legacy_discarded_value_comparison/index.html b/api/macros/json_use_legacy_discarded_value_comparison/index.html new file mode 100644 index 000000000..6e1920cc3 --- /dev/null +++ b/api/macros/json_use_legacy_discarded_value_comparison/index.html @@ -0,0 +1,7 @@ + JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - JSON for Modern C++
Skip to content

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<=> 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 (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 <nlohmann/json.hpp>
+
+...
+

Version history

  • Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/nlohmann_define_type_intrusive/index.html b/api/macros/nlohmann_define_type_intrusive/index.html new file mode 100644 index 000000000..718aeb526 --- /dev/null +++ b/api/macros/nlohmann_define_type_intrusive/index.html @@ -0,0 +1,214 @@ + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT - JSON for Modern C++
Skip to content

NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT

#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)              // (1)
+#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)
+

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, 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 during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
  2. Will use value 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.

Parameters

type (in)
name of the type (class, struct) to serialize/deserialize
member (in)
name of the member variable to serialize/deserialize; up to 64 members can be given as comma-separated list

Default definition

The macros add two friend functions to the class which take care of the serialization and deserialization:

friend void to_json(nlohmann::json&, const type&);
+friend void from_json(const nlohmann::json&, type&);
+

See examples below for the concrete generated code.

Notes

Prerequisites

  1. The type type must be default constructible. See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation.
  2. The macro must be used inside the type (class/struct).

Implementation limits

  • The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json/from_json functions manually.
  • The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported.

Examples

Example (1): NLOHMANN_DEFINE_TYPE_INTRUSIVE

Consider the following complete example:

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    try
+    {
+        auto p3 = j3.get<ns::person>();
+    }
+    catch (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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_)
+    {}
+
+    friend void to_json(nlohmann::json& 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;
+    }
+
+    friend void from_json(const nlohmann::json& 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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    try
+    {
+        auto p3 = j3.get<ns::person>();
+    }
+    catch (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    auto p3 = j3.get<ns::person>();
+    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 <iostream>
+#include <nlohmann/json.hpp>
+
+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_)
+    {}
+
+    friend void to_json(nlohmann::json& 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;
+    }
+
+    friend void from_json(const nlohmann::json& 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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    auto p3 = j3.get<ns::person>();
+    std::cout << "roundtrip: " << json(p3) << std::endl;
+}
+

Note how a default-initialized person object is used in the from_json to fill missing values.

See also

Version history

  1. Added in version 3.9.0.
  2. Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/nlohmann_define_type_non_intrusive/index.html b/api/macros/nlohmann_define_type_non_intrusive/index.html new file mode 100644 index 000000000..07a7e70f8 --- /dev/null +++ b/api/macros/nlohmann_define_type_non_intrusive/index.html @@ -0,0 +1,196 @@ + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT - JSON for Modern C++
Skip to content

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT

#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)              // (1)
+#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2)
+

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, 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 during deserialization and will throw out_of_range.403 if a key is missing in the JSON object.
  2. Will use value 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.

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 64 members can be given as comma-separated list

Default definition

The macros add two functions to the namespace which take care of the serialization and deserialization:

void to_json(nlohmann::json&, const type&);
+void from_json(const nlohmann::json&, type&);
+

See examples below for the concrete generated code.

Notes

Prerequisites

  1. The type type must be default constructible. See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation.
  2. The macro must be used outside the type (class/struct).
  3. The passed members must be public.

Implementation limits

  • The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json/from_json functions manually.
  • The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported.

Examples

Example (1): NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE

Consider the following complete example:

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    try
+    {
+        auto p3 = j3.get<ns::person>();
+    }
+    catch (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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+using namespace nlohmann::literals;
+
+namespace ns
+{
+struct person
+{
+    std::string name;
+    std::string address;
+    int age;
+};
+
+void to_json(nlohmann::json& 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;
+}
+
+void from_json(const nlohmann::json& 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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    try
+    {
+        auto p3 = j3.get<ns::person>();
+    }
+    catch (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 <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    auto p3 = j3.get<ns::person>();
+    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 <iostream>
+#include <nlohmann/json.hpp>
+
+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_)
+    {}
+};
+
+void to_json(nlohmann::json& 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;
+}
+
+void from_json(const nlohmann::json& 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<ns::person>();
+
+    // incomplete deserialization:
+    json j3 = R"({"address": "742 Evergreen Terrace", "name": "Maggie Simpson"})"_json;
+    auto p3 = j3.get<ns::person>();
+    std::cout << "roundtrip: " << json(p3) << std::endl;
+}
+

Note how a default-initialized person object is used in the from_json to fill missing values.

See also

Version history

  1. Added in version 3.9.0.
  2. Added in version 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/nlohmann_json_namespace/index.html b/api/macros/nlohmann_json_namespace/index.html new file mode 100644 index 000000000..7b5ed9d7e --- /dev/null +++ b/api/macros/nlohmann_json_namespace/index.html @@ -0,0 +1,17 @@ + NLOHMANN_JSON_NAMESPACE - JSON for Modern C++
Skip to content

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 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 <iostream>
+#include <nlohmann/json.hpp>
+
+// 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_11_2
+

See also

Version history

  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/nlohmann_json_namespace_begin/index.html b/api/macros/nlohmann_json_namespace_begin/index.html new file mode 100644 index 000000000..02b086388 --- /dev/null +++ b/api/macros/nlohmann_json_namespace_begin/index.html @@ -0,0 +1,43 @@ + NLOHMANN_JSON_NAMESPACE_END - JSON for Modern C++
Skip to content

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 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.

  1. Default definition of NLOHMANN_JSON_NAMESPACE_BEGIN:

    namespace nlohmann
    +{
    +inline namespace json_abi_v3_11_2
    +{
    +
  2. Default definition of NLOHMANN_JSON_NAMESPACE_END:

    }  // namespace json_abi_v3_11_2
    +}  // 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? page.

#include <iostream>
+#include <optional>
+#include <nlohmann/json.hpp>
+
+// partial specialization (see https://json.nlohmann.me/features/arbitrary_types/)
+NLOHMANN_JSON_NAMESPACE_BEGIN
+template <typename T>
+struct adl_serializer<std::optional<T>>
+{
+    static void to_json(json& j, const std::optional<T>& opt)
+    {
+        if (opt == std::nullopt)
+        {
+            j = nullptr;
+        }
+        else
+        {
+            j = *opt;
+        }
+    }
+};
+NLOHMANN_JSON_NAMESPACE_END
+
+int main()
+{
+    std::optional<int> o1 = 1;
+    std::optional<int> 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

Version history

  • Added in version 3.11.0. Changed inline namespace name in version 3.11.2.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/nlohmann_json_namespace_no_version/index.html b/api/macros/nlohmann_json_namespace_no_version/index.html new file mode 100644 index 000000000..15a3955de --- /dev/null +++ b/api/macros/nlohmann_json_namespace_no_version/index.html @@ -0,0 +1,17 @@ + NLOHMANN_JSON_NAMESPACE_NO_VERSION - JSON for Modern C++
Skip to content

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 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 <iostream>
+
+#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 1
+#include <nlohmann/json.hpp>
+
+// 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

Version history

  • Added in version 3.11.2.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/nlohmann_json_serialize_enum/index.html b/api/macros/nlohmann_json_serialize_enum/index.html new file mode 100644 index 000000000..c07b0e786 --- /dev/null +++ b/api/macros/nlohmann_json_serialize_enum/index.html @@ -0,0 +1,104 @@ + NLOHMANN_JSON_SERIALIZE_ENUM - JSON for Modern C++
Skip to content

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 de-serialized 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 macros add two friend functions to the class which take care of the serialization and deserialization:

template<typename BasicJsonType>
+inline void to_json(BasicJsonType& j, const type& e);
+template<typename BasicJsonType>
+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<ENUM_TYPE>(), 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 <iostream>
+#include <nlohmann/json.hpp>
+
+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<ns::TaskState>();
+    auto blue = j_blue.get<ns::Color>();
+    std::cout << j_running << " -> " << running
+              << ", " << j_blue << " -> " << static_cast<int>(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<ns::TaskState>();
+    auto unknown = j_pi.get<ns::Color>();
+    std::cout << j_pi << " -> " << invalid << ", "
+              << j_pi << " -> " << static_cast<int>(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 <iostream>
+#include <nlohmann/json.hpp>
+
+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<int>(ns::Color::red) << " -> " << j_red << std::endl;
+
+    // deserialization
+    json j_rot = "rot";
+    auto rot = j_rot.get<ns::Color>();
+    auto red = j_red.get<ns::Color>();
+    std::cout << j_rot << " -> " << static_cast<int>(rot) << std::endl;
+    std::cout << j_red << " -> " << static_cast<int>(red) << std::endl;
+}
+

Output:

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

See also

Version history

Added in version 3.4.0.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/macros/nlohmann_json_version_major/index.html b/api/macros/nlohmann_json_version_major/index.html new file mode 100644 index 000000000..1d9e69e01 --- /dev/null +++ b/api/macros/nlohmann_json_version_major/index.html @@ -0,0 +1,17 @@ + NLOHMANN_JSON_VERSION_PATCH - JSON for Modern C++
Skip to content

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.

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 <iostream>
+#include <nlohmann/json.hpp>
+
+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.11.2
+

See also

Version history

  • Added in version 3.1.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/operator_gtgt/index.html b/api/operator_gtgt/index.html new file mode 100644 index 000000000..17a104849 --- /dev/null +++ b/api/operator_gtgt/index.html @@ -0,0 +1,41 @@ + operator>>(basic_json) - JSON for Modern C++
Skip to content

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

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.

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 <iostream>
+#include <iomanip>
+#include <sstream>
+#include <nlohmann/json.hpp>
+
+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 - check if the input is valid JSON
  • parse - deserialize from a compatible input

Version history

  • Added in version 1.0.0. Deprecated in version 3.0.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/operator_literal_json/index.html b/api/operator_literal_json/index.html new file mode 100644 index 000000000..082e11097 --- /dev/null +++ b/api/operator_literal_json/index.html @@ -0,0 +1,24 @@ + operator""_json - JSON for Modern C++
Skip to content

nlohmann::operator""_json

json operator "" _json(const char* s, std::size_t n);
+

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 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` for details.

Parameters

s (in)
a string representation of a JSON object
n (in)
length of string s

Return value

json value parsed from s

Exceptions

The function can throw anything that parse(s, s+n) would throw.

Complexity

Linear.

Examples

Example

The following code shows how to create JSON values from string literals.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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"
+}
+

Version history

  • Added in version 1.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/operator_literal_json_pointer/index.html b/api/operator_literal_json_pointer/index.html new file mode 100644 index 000000000..5d7218d91 --- /dev/null +++ b/api/operator_literal_json_pointer/index.html @@ -0,0 +1,22 @@ + operator""_json_pointer - JSON for Modern C++
Skip to content

nlohmann::operator""_json_pointer

json_pointer operator "" _json_pointer(const char* s, std::size_t n);
+

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 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` for details.

Parameters

s (in)
a string representation of a JSON Pointer
n (in)
length of string s

Return value

json_pointer value parsed from s

Exceptions

The function can throw anything that json_pointer::json_pointer would throw.

Complexity

Linear.

Examples

Example

The following code shows how to create JSON Pointers from string literals.

#include <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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

Version history

  • Added in version 2.0.0.
  • Moved to namespace nlohmann::literals::json_literals in 3.11.0.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/operator_ltlt/index.html b/api/operator_ltlt/index.html new file mode 100644 index 000000000..f66b1aedd --- /dev/null +++ b/api/operator_ltlt/index.html @@ -0,0 +1,60 @@ + operator<<(json_pointer) - JSON for Modern C++
Skip to content

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 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 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 if a string stored inside the JSON value is not UTF-8 encoded. Note that unlike the dump member functions, no error_handler can be set.
  2. 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 <iostream>
+#include <iomanip>
+#include <nlohmann/json.hpp>
+
+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 <iostream>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+int main()
+{
+    // create JSON poiner
+    json::json_pointer ptr("/foo/bar/baz");
+
+    // write string representation to stream
+    std::cout << ptr << std::endl;
+}
+

Output:

/foo/bar/baz
+

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.

Last update: March 8, 2023
\ No newline at end of file diff --git a/api/ordered_json/index.html b/api/ordered_json/index.html new file mode 100644 index 000000000..1e347fc14 --- /dev/null +++ b/api/ordered_json/index.html @@ -0,0 +1,21 @@ + ordered_json - JSON for Modern C++
Skip to content

nlohmann::ordered_json

using ordered_json = basic_json<ordered_map>;
+

This type preserves the insertion order of object keys.

Examples

Example

The example below demonstrates how ordered_json preserves the insertion order of object keys.

#include <iostream>
+#include <nlohmann/json.hpp>
+
+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

Version history

Since version 3.9.0.


Last update: March 8, 2023
\ No newline at end of file diff --git a/api/ordered_map/index.html b/api/ordered_map/index.html new file mode 100644 index 000000000..02240d5da --- /dev/null +++ b/api/ordered_map/index.html @@ -0,0 +1,54 @@ + ordered_map - JSON for Modern C++
Skip to content

nlohmann::ordered_map

template<class Key, class T, class IgnoredLess = std::less<Key>,
+         class Allocator = std::allocator<std::pair<const Key, T>>>
+struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>;
+

A minimal map-like container that preserves insertion order for use within nlohmann::ordered_json (nlohmann::basic_json<ordered_map>).

Template parameters

Key
key type
T
mapped type
IgnoredLess
comparison function (ignored and only added to ensure compatibility with std::map)
Allocator
allocator type

Member types

  • key_type - key type (Key)
  • mapped_type - mapped type (T)
  • Container - base container type (std::vector<std::pair<const Key, T>, Allocator>)
  • iterator
  • const_iterator
  • size_type
  • value_type
  • key_compare - key comparison function
    std::equal_to<Key>  // 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 <iostream>
+#include <nlohmann/json.hpp>
+
+// simple output function
+template<typename Map>
+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<std::string, std::string> m_ordered;
+    m_ordered["one"] = "eins";
+    m_ordered["two"] = "zwei";
+    m_ordered["three"] = "drei";
+
+    std::map<std::string, std::string> 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

Version history


Last update: March 8, 2023
\ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf13b9f9d978896599290a74f77d5dbe7d1655c GIT binary patch literal 1870 zcmV-U2eJ5xP)Gc)JR9QMau)O=X#!i9;T z37kk-upj^(fsR36MHs_+1RCI)NNu9}lD0S{B^g8PN?Ww(5|~L#Ng*g{WsqleV}|#l zz8@ri&cTzw_h33bHI+12+kK6WN$h#n5cD8OQt`5kw6p~9H3()bUQ8OS4Q4HTQ=1Ol z_JAocz`fLbT2^{`8n~UAo=#AUOf=SOq4pYkt;XbC&f#7lb$*7=$na!mWCQ`dBQsO0 zLFBSPj*N?#u5&pf2t4XjEGH|=pPQ8xh7tpx;US5Cx_Ju;!O`ya-yF`)b%TEt5>eP1ZX~}sjjA%FJF?h7cX8=b!DZl<6%Cv z*G0uvvU+vmnpLZ2paivG-(cd*y3$hCIcsZcYOGh{$&)A6*XX&kXZd3G8m)G$Zz-LV z^GF3VAW^Mdv!)4OM8EgqRiz~*Cji;uzl2uC9^=8I84vNp;ltJ|q-*uQwGp2ma6cY7 z;`%`!9UXO@fr&Ebapfs34OmS9^u6$)bJxrucutf>`dKPKT%%*d3XlFVKunp9 zasduxjrjs>f8V=D|J=XNZp;_Zy^WgQ$9WDjgY=z@stwiEBm9u5*|34&1Na8BMjjgf3+SHcr`5~>oz1Y?SW^=K z^bTyO6>Gar#P_W2gEMwq)ot3; zREHn~U&Dp0l6YT0&k-wLwYjb?5zGK`W6S2v+K>AM(95m2C20L|3m~rN8dprPr@t)5lsk9Hu*W z?pS990s;Ez=+Rj{x7p``4>+c0G5^pYnB1^!TL=(?HLHZ+HicG{~4F1d^5Awl_2!1jICM-!9eoLhbbT^;yHcefyTAaqRcY zmuctDopPT!%k+}x%lZRKnzykr2}}XfG_ne?nRQO~?%hkzo;@RN{P6o`&mMUWBYMTe z6i8ChtjX&gXl`nvrU>jah)2iNM%JdjqoaeaU%yVn!^70x-flljp6Q5tK}5}&X8&&G zX3fpb3E(!rH=zVI_9Gjl45w@{(ITqngWFe7@9{mX;tO25Z_8 zQHEpI+FkTU#4xu>RkN>b3Tnc3UpWzPXWm#o55GKF09j^Mh~)K7{QqbO_~(@CVq! zS<8954|P8mXN2MRs86xZ&Q4EfM@JB94b=(YGuk)s&^jiSF=t3*oNK3`rD{H`yQ?d; ztE=laAUoZx5?RC8*WKOj`%LXEkgDd>&^Q4M^z`%u0rg-It=hLCVsq!Z%^6eB-OvOT zFZ28TN&cRmgU}Elrnk43)!>Z1FCPL2K$7}gwzIc48NX}#!A1BpJP?#v5wkNprhV** z?Cpalt1oH&{r!o3eSKc&ap)iz2BTn_VV`4>9M^b3;(YY}4>#ML6{~(4mH+?%07*qo IM6N<$f(jP3KmY&$ literal 0 HcmV?d00001 diff --git a/assets/javascripts/bundle.5a2dcb6a.min.js b/assets/javascripts/bundle.5a2dcb6a.min.js new file mode 100644 index 000000000..6f9720b67 --- /dev/null +++ b/assets/javascripts/bundle.5a2dcb6a.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var aa=Object.create;var wr=Object.defineProperty;var sa=Object.getOwnPropertyDescriptor;var ca=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,fa=Object.getPrototypeOf,Er=Object.prototype.hasOwnProperty,fn=Object.prototype.propertyIsEnumerable;var cn=(e,t,r)=>t in e?wr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,H=(e,t)=>{for(var r in t||(t={}))Er.call(t,r)&&cn(e,r,t[r]);if(kt)for(var r of kt(t))fn.call(t,r)&&cn(e,r,t[r]);return e};var un=(e,t)=>{var r={};for(var n in e)Er.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&kt)for(var n of kt(e))t.indexOf(n)<0&&fn.call(e,n)&&(r[n]=e[n]);return r};var yt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var ua=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ca(t))!Er.call(e,o)&&o!==r&&wr(e,o,{get:()=>t[o],enumerable:!(n=sa(t,o))||n.enumerable});return e};var Ye=(e,t,r)=>(r=e!=null?aa(fa(e)):{},ua(t||!e||!e.__esModule?wr(r,"default",{value:e,enumerable:!0}):r,e));var ln=yt((Sr,pn)=>{(function(e,t){typeof Sr=="object"&&typeof pn!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Sr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(_){return!!(_&&_!==document&&_.nodeName!=="HTML"&&_.nodeName!=="BODY"&&"classList"in _&&"contains"in _.classList)}function c(_){var We=_.type,Fe=_.tagName;return!!(Fe==="INPUT"&&s[We]&&!_.readOnly||Fe==="TEXTAREA"&&!_.readOnly||_.isContentEditable)}function f(_){_.classList.contains("focus-visible")||(_.classList.add("focus-visible"),_.setAttribute("data-focus-visible-added",""))}function u(_){!_.hasAttribute("data-focus-visible-added")||(_.classList.remove("focus-visible"),_.removeAttribute("data-focus-visible-added"))}function p(_){_.metaKey||_.altKey||_.ctrlKey||(a(r.activeElement)&&f(r.activeElement),n=!0)}function l(_){n=!1}function d(_){!a(_.target)||(n||c(_.target))&&f(_.target)}function h(_){!a(_.target)||(_.target.classList.contains("focus-visible")||_.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(_.target))}function b(_){document.visibilityState==="hidden"&&(o&&(n=!0),U())}function U(){document.addEventListener("mousemove",W),document.addEventListener("mousedown",W),document.addEventListener("mouseup",W),document.addEventListener("pointermove",W),document.addEventListener("pointerdown",W),document.addEventListener("pointerup",W),document.addEventListener("touchmove",W),document.addEventListener("touchstart",W),document.addEventListener("touchend",W)}function G(){document.removeEventListener("mousemove",W),document.removeEventListener("mousedown",W),document.removeEventListener("mouseup",W),document.removeEventListener("pointermove",W),document.removeEventListener("pointerdown",W),document.removeEventListener("pointerup",W),document.removeEventListener("touchmove",W),document.removeEventListener("touchstart",W),document.removeEventListener("touchend",W)}function W(_){_.target.nodeName&&_.target.nodeName.toLowerCase()==="html"||(n=!1,G())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",l,!0),document.addEventListener("pointerdown",l,!0),document.addEventListener("touchstart",l,!0),document.addEventListener("visibilitychange",b,!0),U(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var mn=yt(Or=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(f){return!1}},r=t(),n=function(f){var u={next:function(){var p=f.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(f){return encodeURIComponent(f).replace(/%20/g,"+")},i=function(f){return decodeURIComponent(String(f).replace(/\+/g," "))},s=function(){var f=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var l=typeof p;if(l!=="undefined")if(l==="string")p!==""&&this._fromString(p);else if(p instanceof f){var d=this;p.forEach(function(G,W){d.append(W,G)})}else if(p!==null&&l==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),f._entries&&(f._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Or);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(c,f){typeof c!="string"&&(c=String(c)),f&&typeof f!="string"&&(f=String(f));var u=document,p;if(f&&(e.location===void 0||f!==e.location.href)){f=f.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=f,u.head.appendChild(p);try{if(p.href.indexOf(f)!==0)throw new Error(p.href)}catch(_){throw new Error("URL unable to set base "+f+" due to "+_)}}var l=u.createElement("a");l.href=c,p&&(u.body.appendChild(l),l.href=l.href);var d=u.createElement("input");if(d.type="url",d.value=c,l.protocol===":"||!/:/.test(l.href)||!d.checkValidity()&&!f)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:l});var h=new e.URLSearchParams(this.search),b=!0,U=!0,G=this;["append","delete","set"].forEach(function(_){var We=h[_];h[_]=function(){We.apply(h,arguments),b&&(U=!1,G.search=h.toString(),U=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var W=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==W&&(W=this.search,U&&(b=!1,this.searchParams._fromString(this.search),b=!0))}})},s=i.prototype,a=function(c){Object.defineProperty(s,c,{get:function(){return this._anchorElement[c]},set:function(f){this._anchorElement[c]=f},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(c){a(c)}),Object.defineProperty(s,"search",{get:function(){return this._anchorElement.search},set:function(c){this._anchorElement.search=c,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(s,{toString:{get:function(){var c=this;return function(){return c.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(c){this._anchorElement.href=c,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(c){this._anchorElement.pathname=c},enumerable:!0},origin:{get:function(){var c={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],f=this._anchorElement.port!=c&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(f?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(c){},enumerable:!0},username:{get:function(){return""},set:function(c){},enumerable:!0}}),i.createObjectURL=function(c){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(c){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Or)});var Pn=yt((Ks,$t)=>{/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */var dn,hn,bn,vn,gn,yn,xn,wn,En,Ht,_r,Sn,On,_n,rt,Tn,Mn,Ln,An,Cn,Rn,kn,Hn,Pt;(function(e){var t=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(n){e(r(t,r(n)))}):typeof $t=="object"&&typeof $t.exports=="object"?e(r(t,r($t.exports))):e(r(t));function r(n,o){return n!==t&&(typeof Object.create=="function"?Object.defineProperty(n,"__esModule",{value:!0}):n.__esModule=!0),function(i,s){return n[i]=o?o(i,s):s}}})(function(e){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,o){n.__proto__=o}||function(n,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(n[i]=o[i])};dn=function(n,o){if(typeof o!="function"&&o!==null)throw new TypeError("Class extends value "+String(o)+" is not a constructor or null");t(n,o);function i(){this.constructor=n}n.prototype=o===null?Object.create(o):(i.prototype=o.prototype,new i)},hn=Object.assign||function(n){for(var o,i=1,s=arguments.length;i=0;u--)(f=n[u])&&(c=(a<3?f(c):a>3?f(o,i,c):f(o,i))||c);return a>3&&c&&Object.defineProperty(o,i,c),c},gn=function(n,o){return function(i,s){o(i,s,n)}},yn=function(n,o){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(n,o)},xn=function(n,o,i,s){function a(c){return c instanceof i?c:new i(function(f){f(c)})}return new(i||(i=Promise))(function(c,f){function u(d){try{l(s.next(d))}catch(h){f(h)}}function p(d){try{l(s.throw(d))}catch(h){f(h)}}function l(d){d.done?c(d.value):a(d.value).then(u,p)}l((s=s.apply(n,o||[])).next())})},wn=function(n,o){var i={label:0,sent:function(){if(c[0]&1)throw c[1];return c[1]},trys:[],ops:[]},s,a,c,f;return f={next:u(0),throw:u(1),return:u(2)},typeof Symbol=="function"&&(f[Symbol.iterator]=function(){return this}),f;function u(l){return function(d){return p([l,d])}}function p(l){if(s)throw new TypeError("Generator is already executing.");for(;i;)try{if(s=1,a&&(c=l[0]&2?a.return:l[0]?a.throw||((c=a.return)&&c.call(a),0):a.next)&&!(c=c.call(a,l[1])).done)return c;switch(a=0,c&&(l=[l[0]&2,c.value]),l[0]){case 0:case 1:c=l;break;case 4:return i.label++,{value:l[1],done:!1};case 5:i.label++,a=l[1],l=[0];continue;case 7:l=i.ops.pop(),i.trys.pop();continue;default:if(c=i.trys,!(c=c.length>0&&c[c.length-1])&&(l[0]===6||l[0]===2)){i=0;continue}if(l[0]===3&&(!c||l[1]>c[0]&&l[1]=n.length&&(n=void 0),{value:n&&n[s++],done:!n}}};throw new TypeError(o?"Object is not iterable.":"Symbol.iterator is not defined.")},_r=function(n,o){var i=typeof Symbol=="function"&&n[Symbol.iterator];if(!i)return n;var s=i.call(n),a,c=[],f;try{for(;(o===void 0||o-- >0)&&!(a=s.next()).done;)c.push(a.value)}catch(u){f={error:u}}finally{try{a&&!a.done&&(i=s.return)&&i.call(s)}finally{if(f)throw f.error}}return c},Sn=function(){for(var n=[],o=0;o1||u(b,U)})})}function u(b,U){try{p(s[b](U))}catch(G){h(c[0][3],G)}}function p(b){b.value instanceof rt?Promise.resolve(b.value.v).then(l,d):h(c[0][2],b)}function l(b){u("next",b)}function d(b){u("throw",b)}function h(b,U){b(U),c.shift(),c.length&&u(c[0][0],c[0][1])}},Mn=function(n){var o,i;return o={},s("next"),s("throw",function(a){throw a}),s("return"),o[Symbol.iterator]=function(){return this},o;function s(a,c){o[a]=n[a]?function(f){return(i=!i)?{value:rt(n[a](f)),done:a==="return"}:c?c(f):f}:c}},Ln=function(n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o=n[Symbol.asyncIterator],i;return o?o.call(n):(n=typeof Ht=="function"?Ht(n):n[Symbol.iterator](),i={},s("next"),s("throw"),s("return"),i[Symbol.asyncIterator]=function(){return this},i);function s(c){i[c]=n[c]&&function(f){return new Promise(function(u,p){f=n[c](f),a(u,p,f.done,f.value)})}}function a(c,f,u,p){Promise.resolve(p).then(function(l){c({value:l,done:u})},f)}},An=function(n,o){return Object.defineProperty?Object.defineProperty(n,"raw",{value:o}):n.raw=o,n};var r=Object.create?function(n,o){Object.defineProperty(n,"default",{enumerable:!0,value:o})}:function(n,o){n.default=o};Cn=function(n){if(n&&n.__esModule)return n;var o={};if(n!=null)for(var i in n)i!=="default"&&Object.prototype.hasOwnProperty.call(n,i)&&Pt(o,n,i);return r(o,n),o},Rn=function(n){return n&&n.__esModule?n:{default:n}},kn=function(n,o,i,s){if(i==="a"&&!s)throw new TypeError("Private accessor was defined without a getter");if(typeof o=="function"?n!==o||!s:!o.has(n))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?s:i==="a"?s.call(n):s?s.value:o.get(n)},Hn=function(n,o,i,s,a){if(s==="m")throw new TypeError("Private method is not writable");if(s==="a"&&!a)throw new TypeError("Private accessor was defined without a setter");if(typeof o=="function"?n!==o||!a:!o.has(n))throw new TypeError("Cannot write private member to an object whose class did not declare it");return s==="a"?a.call(n,i):a?a.value=i:o.set(n,i),i},e("__extends",dn),e("__assign",hn),e("__rest",bn),e("__decorate",vn),e("__param",gn),e("__metadata",yn),e("__awaiter",xn),e("__generator",wn),e("__exportStar",En),e("__createBinding",Pt),e("__values",Ht),e("__read",_r),e("__spread",Sn),e("__spreadArrays",On),e("__spreadArray",_n),e("__await",rt),e("__asyncGenerator",Tn),e("__asyncDelegator",Mn),e("__asyncValues",Ln),e("__makeTemplateObject",An),e("__importStar",Cn),e("__importDefault",Rn),e("__classPrivateFieldGet",kn),e("__classPrivateFieldSet",Hn)})});var Br=yt((At,Yr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof At=="object"&&typeof Yr=="object"?Yr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof At=="object"?At.ClipboardJS=r():t.ClipboardJS=r()})(At,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return ia}});var s=i(279),a=i.n(s),c=i(370),f=i.n(c),u=i(817),p=i.n(u);function l(j){try{return document.execCommand(j)}catch(T){return!1}}var d=function(T){var O=p()(T);return l("cut"),O},h=d;function b(j){var T=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[T?"right":"left"]="-9999px";var k=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(k,"px"),O.setAttribute("readonly",""),O.value=j,O}var U=function(T,O){var k=b(T);O.container.appendChild(k);var $=p()(k);return l("copy"),k.remove(),$},G=function(T){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},k="";return typeof T=="string"?k=U(T,O):T instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(T==null?void 0:T.type)?k=U(T.value,O):(k=p()(T),l("copy")),k},W=G;function _(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?_=function(O){return typeof O}:_=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},_(j)}var We=function(){var T=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=T.action,k=O===void 0?"copy":O,$=T.container,q=T.target,Te=T.text;if(k!=="copy"&&k!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&_(q)==="object"&&q.nodeType===1){if(k==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(k==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Te)return W(Te,{container:$});if(q)return k==="cut"?h(q):W(q,{container:$})},Fe=We;function Pe(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Pe=function(O){return typeof O}:Pe=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Pe(j)}function Ji(j,T){if(!(j instanceof T))throw new TypeError("Cannot call a class as a function")}function sn(j,T){for(var O=0;O0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof $.action=="function"?$.action:this.defaultAction,this.target=typeof $.target=="function"?$.target:this.defaultTarget,this.text=typeof $.text=="function"?$.text:this.defaultText,this.container=Pe($.container)==="object"?$.container:document.body}},{key:"listenClick",value:function($){var q=this;this.listener=f()($,"click",function(Te){return q.onClick(Te)})}},{key:"onClick",value:function($){var q=$.delegateTarget||$.currentTarget,Te=this.action(q)||"copy",Rt=Fe({action:Te,container:this.container,target:this.target(q),text:this.text(q)});this.emit(Rt?"success":"error",{action:Te,text:Rt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function($){return xr("action",$)}},{key:"defaultTarget",value:function($){var q=xr("target",$);if(q)return document.querySelector(q)}},{key:"defaultText",value:function($){return xr("text",$)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function($){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return W($,q)}},{key:"cut",value:function($){return h($)}},{key:"isSupported",value:function(){var $=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof $=="string"?[$]:$,Te=!!document.queryCommandSupported;return q.forEach(function(Rt){Te=Te&&!!document.queryCommandSupported(Rt)}),Te}}]),O}(a()),ia=oa},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==o;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}n.exports=s},438:function(n,o,i){var s=i(828);function a(u,p,l,d,h){var b=f.apply(this,arguments);return u.addEventListener(l,b,h),{destroy:function(){u.removeEventListener(l,b,h)}}}function c(u,p,l,d,h){return typeof u.addEventListener=="function"?a.apply(null,arguments):typeof l=="function"?a.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(b){return a(b,p,l,d,h)}))}function f(u,p,l,d){return function(h){h.delegateTarget=s(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=c},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(n,o,i){var s=i(879),a=i(438);function c(l,d,h){if(!l&&!d&&!h)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(h))throw new TypeError("Third argument must be a Function");if(s.node(l))return f(l,d,h);if(s.nodeList(l))return u(l,d,h);if(s.string(l))return p(l,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function f(l,d,h){return l.addEventListener(d,h),{destroy:function(){l.removeEventListener(d,h)}}}function u(l,d,h){return Array.prototype.forEach.call(l,function(b){b.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(l,function(b){b.removeEventListener(d,h)})}}}function p(l,d,h){return a(document.body,l,d,h)}n.exports=c},817:function(n){function o(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),f=document.createRange();f.selectNodeContents(i),c.removeAllRanges(),c.addRange(f),s=c.toString()}return s}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function f(){c.off(i,f),s.apply(a,arguments)}return f._=s,this.on(i,f,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,f=a.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Ms=/["'&<>]/;Si.exports=Ls;function Ls(e){var t=""+e,r=Ms.exec(t);if(!r)return t;var n,o="",i=0,s=0;for(i=r.index;i0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,s=o.isStopped,a=o.observers;return i||s?Tr:(this.currentObservers=null,a.push(r),new $e(function(){n.currentObservers=null,Ue(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,s=n.isStopped;o?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new Qn(r,n)},t}(F);var Qn=function(e){ne(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Tr},t}(E);var wt={now:function(){return(wt.delegate||Date).now()},delegate:void 0};var Et=function(e){ne(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=wt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,s=n._infiniteTimeWindow,a=n._timestampProvider,c=n._windowTime;o||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,s=o._buffer,a=s.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=at.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var s=r.actions;n!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==n&&(at.cancelAnimationFrame(n),r._scheduled=void 0)},t}(zt);var Gn=function(e){ne(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Nt);var xe=new Gn(Bn);var R=new F(function(e){return e.complete()});function qt(e){return e&&L(e.schedule)}function Hr(e){return e[e.length-1]}function Ve(e){return L(Hr(e))?e.pop():void 0}function Ee(e){return qt(Hr(e))?e.pop():void 0}function Kt(e,t){return typeof Hr(e)=="number"?e.pop():t}var st=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Qt(e){return L(e==null?void 0:e.then)}function Yt(e){return L(e[it])}function Bt(e){return Symbol.asyncIterator&&L(e==null?void 0:e[Symbol.asyncIterator])}function Gt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function ya(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Jt=ya();function Xt(e){return L(e==null?void 0:e[Jt])}function Zt(e){return jn(this,arguments,function(){var r,n,o,i;return It(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,jt(r.read())];case 3:return n=s.sent(),o=n.value,i=n.done,i?[4,jt(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,jt(o)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function er(e){return L(e==null?void 0:e.getReader)}function z(e){if(e instanceof F)return e;if(e!=null){if(Yt(e))return xa(e);if(st(e))return wa(e);if(Qt(e))return Ea(e);if(Bt(e))return Jn(e);if(Xt(e))return Sa(e);if(er(e))return Oa(e)}throw Gt(e)}function xa(e){return new F(function(t){var r=e[it]();if(L(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function wa(e){return new F(function(t){for(var r=0;r=2,!0))}function ie(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(f){var u,p,l,d=0,h=!1,b=!1,U=function(){p==null||p.unsubscribe(),p=void 0},G=function(){U(),u=l=void 0,h=b=!1},W=function(){var _=u;G(),_==null||_.unsubscribe()};return g(function(_,We){d++,!b&&!h&&U();var Fe=l=l!=null?l:r();We.add(function(){d--,d===0&&!b&&!h&&(p=Dr(W,c))}),Fe.subscribe(We),!u&&d>0&&(u=new Ge({next:function(Pe){return Fe.next(Pe)},error:function(Pe){b=!0,U(),p=Dr(G,o,Pe),Fe.error(Pe)},complete:function(){h=!0,U(),p=Dr(G,s),Fe.complete()}}),z(_).subscribe(u))})(f)}}function Dr(e,t){for(var r=[],n=2;ne.next(document)),e}function Q(e,t=document){return Array.from(t.querySelectorAll(e))}function K(e,t=document){let r=pe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function pe(e,t=document){return t.querySelector(e)||void 0}function Ie(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function nr(e){return A(v(document.body,"focusin"),v(document.body,"focusout")).pipe(Re(1),m(()=>{let t=Ie();return typeof t!="undefined"?e.contains(t):!1}),N(e===Ie()),B())}function qe(e){return{x:e.offsetLeft,y:e.offsetTop}}function yo(e){return A(v(window,"load"),v(window,"resize")).pipe(Ae(0,xe),m(()=>qe(e)),N(qe(e)))}function or(e){return{x:e.scrollLeft,y:e.scrollTop}}function pt(e){return A(v(e,"scroll"),v(window,"resize")).pipe(Ae(0,xe),m(()=>or(e)),N(or(e)))}var wo=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!qr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),Ka?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!qr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=qa.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Eo=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Oo=typeof WeakMap!="undefined"?new WeakMap:new wo,_o=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=Qa.getInstance(),n=new ns(t,r,this);Oo.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){_o.prototype[e]=function(){var t;return(t=Oo.get(this))[e].apply(t,arguments)}});var os=function(){return typeof ir.ResizeObserver!="undefined"?ir.ResizeObserver:_o}(),To=os;var Mo=new E,is=P(()=>I(new To(e=>{for(let t of e)Mo.next(t)}))).pipe(S(e=>A(Se,I(e)).pipe(C(()=>e.disconnect()))),X(1));function he(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ve(e){return is.pipe(w(t=>t.observe(e)),S(t=>Mo.pipe(x(({target:r})=>r===e),C(()=>t.unobserve(e)),m(()=>he(e)))),N(he(e)))}function mt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function cr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var Lo=new E,as=P(()=>I(new IntersectionObserver(e=>{for(let t of e)Lo.next(t)},{threshold:0}))).pipe(S(e=>A(Se,I(e)).pipe(C(()=>e.disconnect()))),X(1));function fr(e){return as.pipe(w(t=>t.observe(e)),S(t=>Lo.pipe(x(({target:r})=>r===e),C(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Ao(e,t=16){return pt(e).pipe(m(({y:r})=>{let n=he(e),o=mt(e);return r>=o.height-n.height-t}),B())}var ur={drawer:K("[data-md-toggle=drawer]"),search:K("[data-md-toggle=search]")};function Co(e){return ur[e].checked}function Ke(e,t){ur[e].checked!==t&&ur[e].click()}function dt(e){let t=ur[e];return v(t,"change").pipe(m(()=>t.checked),N(t.checked))}function ss(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ro(){return v(window,"keydown").pipe(x(e=>!(e.metaKey||e.ctrlKey)),m(e=>({mode:Co("search")?"search":"global",type:e.key,claim(){e.preventDefault(),e.stopPropagation()}})),x(({mode:e,type:t})=>{if(e==="global"){let r=Ie();if(typeof r!="undefined")return!ss(r,t)}return!0}),ie())}function Oe(){return new URL(location.href)}function pr(e){location.href=e.href}function ko(){return new E}function Ho(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Ho(e,r)}function M(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)Ho(n,o);return n}function Po(e,t){let r=t;if(e.length>r){for(;e[r]!==" "&&--r>0;);return`${e.substring(0,r)}...`}return e}function lr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function $o(){return location.hash.substring(1)}function Io(e){let t=M("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function cs(){return v(window,"hashchange").pipe(m($o),N($o()),x(e=>e.length>0),X(1))}function jo(){return cs().pipe(m(e=>pe(`[id="${e}"]`)),x(e=>typeof e!="undefined"))}function Kr(e){let t=matchMedia(e);return rr(r=>t.addListener(()=>r(t.matches))).pipe(N(t.matches))}function Fo(){let e=matchMedia("print");return A(v(window,"beforeprint").pipe(m(()=>!0)),v(window,"afterprint").pipe(m(()=>!1))).pipe(N(e.matches))}function Qr(e,t){return e.pipe(S(r=>r?t():R))}function mr(e,t={credentials:"same-origin"}){return ue(fetch(`${e}`,t)).pipe(ce(()=>R),S(r=>r.status!==200?Ot(()=>new Error(r.statusText)):I(r)))}function je(e,t){return mr(e,t).pipe(S(r=>r.json()),X(1))}function Uo(e,t){let r=new DOMParser;return mr(e,t).pipe(S(n=>n.text()),m(n=>r.parseFromString(n,"text/xml")),X(1))}function Do(e){let t=M("script",{src:e});return P(()=>(document.head.appendChild(t),A(v(t,"load"),v(t,"error").pipe(S(()=>Ot(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),C(()=>document.head.removeChild(t)),oe(1))))}function Wo(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function Vo(){return A(v(window,"scroll",{passive:!0}),v(window,"resize",{passive:!0})).pipe(m(Wo),N(Wo()))}function zo(){return{width:innerWidth,height:innerHeight}}function No(){return v(window,"resize",{passive:!0}).pipe(m(zo),N(zo()))}function qo(){return Y([Vo(),No()]).pipe(m(([e,t])=>({offset:e,size:t})),X(1))}function dr(e,{viewport$:t,header$:r}){let n=t.pipe(J("size")),o=Y([n,r]).pipe(m(()=>qe(e)));return Y([r,t,o]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:f}])=>({offset:{x:s.x-c,y:s.y-f+i},size:a})))}function Ko(e,{tx$:t}){let r=v(e,"message").pipe(m(({data:n})=>n));return t.pipe(Lt(()=>r,{leading:!0,trailing:!0}),w(n=>e.postMessage(n)),S(()=>r),ie())}var fs=K("#__config"),ht=JSON.parse(fs.textContent);ht.base=`${new URL(ht.base,Oe())}`;function le(){return ht}function Z(e){return ht.features.includes(e)}function re(e,t){return typeof t!="undefined"?ht.translations[e].replace("#",t.toString()):ht.translations[e]}function _e(e,t=document){return K(`[data-md-component=${e}]`,t)}function te(e,t=document){return Q(`[data-md-component=${e}]`,t)}function us(e){let t=K(".md-typeset > :first-child",e);return v(t,"click",{once:!0}).pipe(m(()=>K(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function Qo(e){return!Z("announce.dismiss")||!e.childElementCount?R:P(()=>{let t=new E;return t.pipe(N({hash:__md_get("__announce")})).subscribe(({hash:r})=>{var n;r&&r===((n=__md_get("__announce"))!=null?n:r)&&(e.hidden=!0,__md_set("__announce",r))}),us(e).pipe(w(r=>t.next(r)),C(()=>t.complete()),m(r=>H({ref:e},r)))})}function ps(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function Yo(e,t){let r=new E;return r.subscribe(({hidden:n})=>{e.hidden=n}),ps(e,t).pipe(w(n=>r.next(n)),C(()=>r.complete()),m(n=>H({ref:e},n)))}var ii=Ye(Br());function Gr(e){return M("div",{class:"md-tooltip",id:e},M("div",{class:"md-tooltip__inner md-typeset"}))}function Bo(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return M("aside",{class:"md-annotation",tabIndex:0},Gr(t),M("a",{href:r,class:"md-annotation__index",tabIndex:-1},M("span",{"data-md-annotation-id":e})))}else return M("aside",{class:"md-annotation",tabIndex:0},Gr(t),M("span",{class:"md-annotation__index",tabIndex:-1},M("span",{"data-md-annotation-id":e})))}function Go(e){return M("button",{class:"md-clipboard md-icon",title:re("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Jr(e,t){let r=t&2,n=t&1,o=Object.keys(e.terms).filter(a=>!e.terms[a]).reduce((a,c)=>[...a,M("del",null,c)," "],[]).slice(0,-1),i=new URL(e.location);Z("search.highlight")&&i.searchParams.set("h",Object.entries(e.terms).filter(([,a])=>a).reduce((a,[c])=>`${a} ${c}`.trim(),""));let{tags:s}=le();return M("a",{href:`${i}`,class:"md-search-result__link",tabIndex:-1},M("article",{class:["md-search-result__article",...r?["md-search-result__article--document"]:[]].join(" "),"data-md-score":e.score.toFixed(2)},r>0&&M("div",{class:"md-search-result__icon md-icon"}),M("h1",{class:"md-search-result__title"},e.title),n>0&&e.text.length>0&&M("p",{class:"md-search-result__teaser"},Po(e.text,320)),e.tags&&M("div",{class:"md-typeset"},e.tags.map(a=>{let c=a.replace(/<[^>]+>/g,""),f=s?c in s?`md-tag-icon md-tag-icon--${s[c]}`:"md-tag-icon":"";return M("span",{class:`md-tag ${f}`},a)})),n>0&&o.length>0&&M("p",{class:"md-search-result__terms"},re("search.result.term.missing"),": ",...o)))}function Jo(e){let t=e[0].score,r=[...e],n=r.findIndex(f=>!f.location.includes("#")),[o]=r.splice(n,1),i=r.findIndex(f=>f.scoreJr(f,1)),...a.length?[M("details",{class:"md-search-result__more"},M("summary",{tabIndex:-1},a.length>0&&a.length===1?re("search.result.more.one"):re("search.result.more.other",a.length)),...a.map(f=>Jr(f,1)))]:[]];return M("li",{class:"md-search-result__item"},c)}function Xo(e){return M("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>M("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?lr(r):r)))}function Xr(e){let t=`tabbed-control tabbed-control--${e}`;return M("div",{class:t,hidden:!0},M("button",{class:"tabbed-button",tabIndex:-1}))}function Zo(e){return M("div",{class:"md-typeset__scrollwrap"},M("div",{class:"md-typeset__table"},e))}function ls(e){let t=le(),r=new URL(`../${e.version}/`,t.base);return M("li",{class:"md-version__item"},M("a",{href:`${r}`,class:"md-version__link"},e.title))}function ei(e,t){return M("div",{class:"md-version"},M("button",{class:"md-version__current","aria-label":re("select.version.title")},t.title),M("ul",{class:"md-version__list"},e.map(ls)))}function ms(e,t){let r=P(()=>Y([yo(e),pt(t)])).pipe(m(([{x:n,y:o},i])=>{let{width:s,height:a}=he(e);return{x:n-i.x+s/2,y:o-i.y+a/2}}));return nr(e).pipe(S(n=>r.pipe(m(o=>({active:n,offset:o})),oe(+!n||1/0))))}function ti(e,t,{target$:r}){let[n,o]=Array.from(e.children);return P(()=>{let i=new E,s=i.pipe(de(1));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),fr(e).pipe(ee(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),A(i.pipe(x(({active:a})=>a)),i.pipe(Re(250),x(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(n):n.remove()},complete(){e.prepend(n)}}),i.pipe(Ae(16,xe)).subscribe(({active:a})=>{n.classList.toggle("md-tooltip--active",a)}),i.pipe(zr(125,xe),x(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),v(o,"click").pipe(ee(s),x(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>a.preventDefault()),v(o,"mousedown").pipe(ee(s),ae(i)).subscribe(([a,{active:c}])=>{var f;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let u=e.parentElement.closest(".md-annotation");u instanceof HTMLElement?u.focus():(f=Ie())==null||f.blur()}}),r.pipe(ee(s),x(a=>a===n),ke(125)).subscribe(()=>e.focus()),ms(e,t).pipe(w(a=>i.next(a)),C(()=>i.complete()),m(a=>H({ref:e},a)))})}function ds(e){let t=[];for(let r of Q(".c, .c1, .cm",e)){let n=[],o=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=o.nextNode();i;i=o.nextNode())n.push(i);for(let i of n){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let f=i.splitText(s.index);i=f.splitText(a.length),t.push(f)}else{i.textContent=a,t.push(i);break}}}}return t}function ri(e,t){t.append(...Array.from(e.childNodes))}function ni(e,t,{target$:r,print$:n}){let o=t.closest("[id]"),i=o==null?void 0:o.id,s=new Map;for(let a of ds(t)){let[,c]=a.textContent.match(/\((\d+)\)/);pe(`li:nth-child(${c})`,e)&&(s.set(c,Bo(c,i)),a.replaceWith(s.get(c)))}return s.size===0?R:P(()=>{let a=new E,c=[];for(let[f,u]of s)c.push([K(".md-typeset",u),K(`li:nth-child(${f})`,e)]);return n.pipe(ee(a.pipe(de(1)))).subscribe(f=>{e.hidden=!f;for(let[u,p]of c)f?ri(u,p):ri(p,u)}),A(...[...s].map(([,f])=>ti(f,t,{target$:r}))).pipe(C(()=>a.complete()),ie())})}var hs=0;function ai(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return ai(t)}}function oi(e){return ve(e).pipe(m(({width:t})=>({scrollable:mt(e).width>t})),J("scrollable"))}function si(e,t){let{matches:r}=matchMedia("(hover)"),n=P(()=>{let o=new E;if(o.subscribe(({scrollable:s})=>{s&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")}),ii.default.isSupported()){let s=e.closest("pre");s.id=`__code_${++hs}`,s.insertBefore(Go(s.id),e)}let i=e.closest(".highlight");if(i instanceof HTMLElement){let s=ai(i);if(typeof s!="undefined"&&(i.classList.contains("annotate")||Z("content.code.annotate"))){let a=ni(s,e,t);return oi(e).pipe(w(c=>o.next(c)),C(()=>o.complete()),m(c=>H({ref:e},c)),et(ve(i).pipe(m(({width:c,height:f})=>c&&f),B(),S(c=>c?a:R))))}}return oi(e).pipe(w(s=>o.next(s)),C(()=>o.complete()),m(s=>H({ref:e},s)))});return Z("content.lazy")?fr(e).pipe(x(o=>o),oe(1),S(()=>n)):n}var ci=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color)}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}defs #flowchart-circleEnd,defs #flowchart-circleStart,defs #flowchart-crossEnd,defs #flowchart-crossStart,defs #flowchart-pointEnd,defs #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}.actor,defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{stroke:var(--md-mermaid-node-fg-color)}text.actor>tspan{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-default-fg-color--lighter)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-edge-color)}.loopText>tspan,.messageText,.noteText>tspan{fill:var(--md-mermaid-edge-color);stroke:none;font-family:var(--md-mermaid-font-family)!important}.noteText>tspan{fill:#000}#arrowhead path{fill:var(--md-mermaid-edge-color);stroke:none}.loopLine{stroke:var(--md-mermaid-node-fg-color)}.labelBox,.loopLine{fill:var(--md-mermaid-node-bg-color)}.labelBox{stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-node-fg-color);font-family:var(--md-mermaid-font-family)}";var Zr,vs=0;function gs(){return typeof mermaid=="undefined"||mermaid instanceof Element?Do("https://unpkg.com/mermaid@9.1.7/dist/mermaid.min.js"):I(void 0)}function fi(e){return e.classList.remove("mermaid"),Zr||(Zr=gs().pipe(w(()=>mermaid.initialize({startOnLoad:!1,themeCSS:ci,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),X(1))),Zr.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${vs++}`,r=M("div",{class:"mermaid"});mermaid.mermaidAPI.render(t,e.textContent,n=>{let o=r.attachShadow({mode:"closed"});o.innerHTML=n,e.replaceWith(r)})}),Zr.pipe(m(()=>({ref:e})))}function ys(e,{target$:t,print$:r}){let n=!0;return A(t.pipe(m(o=>o.closest("details:not([open])")),x(o=>e===o),m(()=>({action:"open",reveal:!0}))),r.pipe(x(o=>o||!n),w(()=>n=e.open),m(o=>({action:o?"open":"close"}))))}function ui(e,t){return P(()=>{let r=new E;return r.subscribe(({action:n,reveal:o})=>{e.toggleAttribute("open",n==="open"),o&&e.scrollIntoView()}),ys(e,t).pipe(w(n=>r.next(n)),C(()=>r.complete()),m(n=>H({ref:e},n)))})}var pi=M("table");function li(e){return e.replaceWith(pi),pi.replaceWith(Zo(e)),I({ref:e})}function xs(e){let t=Q(":scope > input",e),r=t.find(n=>n.checked)||t[0];return A(...t.map(n=>v(n,"change").pipe(m(()=>K(`label[for="${n.id}"]`))))).pipe(N(K(`label[for="${r.id}"]`)),m(n=>({active:n})))}function mi(e,{viewport$:t}){let r=Xr("prev");e.append(r);let n=Xr("next");e.append(n);let o=K(".tabbed-labels",e);return P(()=>{let i=new E,s=i.pipe(de(1));return Y([i,ve(e)]).pipe(Ae(1,xe),ee(s)).subscribe({next([{active:a},c]){let f=qe(a),{width:u}=he(a);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let p=or(o);(f.xp.x+c.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),Y([pt(o),ve(o)]).pipe(ee(s)).subscribe(([a,c])=>{let f=mt(o);r.hidden=a.x<16,n.hidden=a.x>f.width-c.width-16}),A(v(r,"click").pipe(m(()=>-1)),v(n,"click").pipe(m(()=>1))).pipe(ee(s)).subscribe(a=>{let{width:c}=he(o);o.scrollBy({left:c*a,behavior:"smooth"})}),Z("content.tabs.link")&&i.pipe(He(1),ae(t)).subscribe(([{active:a},{offset:c}])=>{let f=a.innerText.trim();if(a.hasAttribute("data-md-switching"))a.removeAttribute("data-md-switching");else{let u=e.offsetTop-c.y;for(let l of Q("[data-tabs]"))for(let d of Q(":scope > input",l)){let h=K(`label[for="${d.id}"]`);if(h!==a&&h.innerText.trim()===f){h.setAttribute("data-md-switching",""),d.click();break}}window.scrollTo({top:e.offsetTop-u});let p=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...p])])}}),xs(e).pipe(w(a=>i.next(a)),C(()=>i.complete()),m(a=>H({ref:e},a)))}).pipe(Je(fe))}function di(e,{viewport$:t,target$:r,print$:n}){return A(...Q("pre:not(.mermaid) > code",e).map(o=>si(o,{target$:r,print$:n})),...Q("pre.mermaid",e).map(o=>fi(o)),...Q("table:not([class])",e).map(o=>li(o)),...Q("details",e).map(o=>ui(o,{target$:r,print$:n})),...Q("[data-tabs]",e).map(o=>mi(o,{viewport$:t})))}function ws(e,{alert$:t}){return t.pipe(S(r=>A(I(!0),I(!1).pipe(ke(2e3))).pipe(m(n=>({message:r,active:n})))))}function hi(e,t){let r=K(".md-typeset",e);return P(()=>{let n=new E;return n.subscribe(({message:o,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=o}),ws(e,t).pipe(w(o=>n.next(o)),C(()=>n.complete()),m(o=>H({ref:e},o)))})}function Es({viewport$:e}){if(!Z("header.autohide"))return I(!1);let t=e.pipe(m(({offset:{y:o}})=>o),Ce(2,1),m(([o,i])=>[oMath.abs(i-o.y)>100),m(([,[o]])=>o),B()),n=dt("search");return Y([e,n]).pipe(m(([{offset:o},i])=>o.y>400&&!i),B(),S(o=>o?r:I(!1)),N(!1))}function bi(e,t){return P(()=>Y([ve(e),Es(t)])).pipe(m(([{height:r},n])=>({height:r,hidden:n})),B((r,n)=>r.height===n.height&&r.hidden===n.hidden),X(1))}function vi(e,{header$:t,main$:r}){return P(()=>{let n=new E,o=n.pipe(de(1));return n.pipe(J("active"),Ze(t)).subscribe(([{active:i},{hidden:s}])=>{e.classList.toggle("md-header--shadow",i&&!s),e.hidden=s}),r.subscribe(n),t.pipe(ee(o),m(i=>H({ref:e},i)))})}function Ss(e,{viewport$:t,header$:r}){return dr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:n}})=>{let{height:o}=he(e);return{active:n>=o}}),J("active"))}function gi(e,t){return P(()=>{let r=new E;r.subscribe(({active:o})=>{e.classList.toggle("md-header__title--active",o)});let n=pe("article h1");return typeof n=="undefined"?R:Ss(n,t).pipe(w(o=>r.next(o)),C(()=>r.complete()),m(o=>H({ref:e},o)))})}function yi(e,{viewport$:t,header$:r}){let n=r.pipe(m(({height:i})=>i),B()),o=n.pipe(S(()=>ve(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),J("bottom"))));return Y([n,o,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:f}}])=>(f=Math.max(0,f-Math.max(0,s-c,i)-Math.max(0,f+c-a)),{offset:s-i,height:f,active:s-i<=c})),B((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function Os(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return I(...e).pipe(se(r=>v(r,"change").pipe(m(()=>r))),N(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),X(1))}function xi(e){return P(()=>{let t=new E;t.subscribe(n=>{document.body.setAttribute("data-md-color-switching","");for(let[o,i]of Object.entries(n.color))document.body.setAttribute(`data-md-color-${o}`,i);for(let o=0;o{document.body.removeAttribute("data-md-color-switching")});let r=Q("input",e);return Os(r).pipe(w(n=>t.next(n)),C(()=>t.complete()),m(n=>H({ref:e},n)))})}var en=Ye(Br());function _s(e){e.setAttribute("data-md-copying","");let t=e.innerText;return e.removeAttribute("data-md-copying"),t}function wi({alert$:e}){en.default.isSupported()&&new F(t=>{new en.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||_s(K(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(w(t=>{t.trigger.focus()}),m(()=>re("clipboard.copied"))).subscribe(e)}function Ts(e){if(e.length<2)return[""];let[t,r]=[...e].sort((o,i)=>o.length-i.length).map(o=>o.replace(/[^/]+$/,"")),n=0;if(t===r)n=t.length;else for(;t.charCodeAt(n)===r.charCodeAt(n);)n++;return e.map(o=>o.replace(t.slice(0,n),""))}function hr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return I(t);{let r=le();return Uo(new URL("sitemap.xml",e||r.base)).pipe(m(n=>Ts(Q("loc",n).map(o=>o.textContent))),ce(()=>R),De([]),w(n=>__md_set("__sitemap",n,sessionStorage,e)))}}function Ei({document$:e,location$:t,viewport$:r}){let n=le();if(location.protocol==="file:")return;"scrollRestoration"in history&&(history.scrollRestoration="manual",v(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}));let o=pe("link[rel=icon]");typeof o!="undefined"&&(o.href=o.href);let i=hr().pipe(m(f=>f.map(u=>`${new URL(u,n.base)}`)),S(f=>v(document.body,"click").pipe(x(u=>!u.metaKey&&!u.ctrlKey),S(u=>{if(u.target instanceof Element){let p=u.target.closest("a");if(p&&!p.target){let l=new URL(p.href);if(l.search="",l.hash="",l.pathname!==location.pathname&&f.includes(l.toString()))return u.preventDefault(),I({url:new URL(p.href)})}}return Se}))),ie()),s=v(window,"popstate").pipe(x(f=>f.state!==null),m(f=>({url:new URL(location.href),offset:f.state})),ie());A(i,s).pipe(B((f,u)=>f.url.href===u.url.href),m(({url:f})=>f)).subscribe(t);let a=t.pipe(J("pathname"),S(f=>mr(f.href).pipe(ce(()=>(pr(f),Se)))),ie());i.pipe(ut(a)).subscribe(({url:f})=>{history.pushState({},"",`${f}`)});let c=new DOMParser;a.pipe(S(f=>f.text()),m(f=>c.parseFromString(f,"text/html"))).subscribe(e),e.pipe(He(1)).subscribe(f=>{for(let u of["title","link[rel=canonical]","meta[name=author]","meta[name=description]","[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...Z("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let p=pe(u),l=pe(u,f);typeof p!="undefined"&&typeof l!="undefined"&&p.replaceWith(l)}}),e.pipe(He(1),m(()=>_e("container")),S(f=>Q("script",f)),Ir(f=>{let u=M("script");if(f.src){for(let p of f.getAttributeNames())u.setAttribute(p,f.getAttribute(p));return f.replaceWith(u),new F(p=>{u.onload=()=>p.complete()})}else return u.textContent=f.textContent,f.replaceWith(u),R})).subscribe(),A(i,s).pipe(ut(e)).subscribe(({url:f,offset:u})=>{f.hash&&!u?Io(f.hash):window.scrollTo(0,(u==null?void 0:u.y)||0)}),r.pipe(Mt(i),Re(250),J("offset")).subscribe(({offset:f})=>{history.replaceState(f,"")}),A(i,s).pipe(Ce(2,1),x(([f,u])=>f.url.pathname===u.url.pathname),m(([,f])=>f)).subscribe(({offset:f})=>{window.scrollTo(0,(f==null?void 0:f.y)||0)})}var As=Ye(tn());var Oi=Ye(tn());function rn(e,t){let r=new RegExp(e.separator,"img"),n=(o,i,s)=>`${i}${s}`;return o=>{o=o.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator})(${o.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(t?(0,Oi.default)(s):s).replace(i,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function _i(e){return e.split(/"([^"]+)"/g).map((t,r)=>r&1?t.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g," +"):t).join("").replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g,"").trim()}function bt(e){return e.type===1}function Ti(e){return e.type===2}function vt(e){return e.type===3}function Rs({config:e,docs:t}){e.lang.length===1&&e.lang[0]==="en"&&(e.lang=[re("search.config.lang")]),e.separator==="[\\s\\-]+"&&(e.separator=re("search.config.separator"));let n={pipeline:re("search.config.pipeline").split(/\s*,\s*/).filter(Boolean),suggestions:Z("search.suggest")};return{config:e,docs:t,options:n}}function Mi(e,t){let r=le(),n=new Worker(e),o=new E,i=Ko(n,{tx$:o}).pipe(m(s=>{if(vt(s))for(let a of s.data.items)for(let c of a)c.location=`${new URL(c.location,r.base)}`;return s}),ie());return ue(t).pipe(m(s=>({type:0,data:Rs(s)}))).subscribe(o.next.bind(o)),{tx$:o,rx$:i}}function Li({document$:e}){let t=le(),r=je(new URL("../versions.json",t.base)).pipe(ce(()=>R)),n=r.pipe(m(o=>{let[,i]=t.base.match(/([^/]+)\/?$/);return o.find(({version:s,aliases:a})=>s===i||a.includes(i))||o[0]}));r.pipe(m(o=>new Map(o.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),S(o=>v(document.body,"click").pipe(x(i=>!i.metaKey&&!i.ctrlKey),ae(n),S(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&o.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&o.get(c)===s?R:(i.preventDefault(),I(c))}}return R}),S(i=>{let{version:s}=o.get(i);return hr(new URL(i)).pipe(m(a=>{let f=Oe().href.replace(t.base,"");return a.includes(f.split("#")[0])?new URL(`../${s}/${f}`,t.base):new URL(i)}))})))).subscribe(o=>pr(o)),Y([r,n]).subscribe(([o,i])=>{K(".md-header__topic").appendChild(ei(o,i))}),e.pipe(S(()=>n)).subscribe(o=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){let a=((s=t.version)==null?void 0:s.default)||"latest";i=!o.aliases.includes(a),__md_set("__outdated",i,sessionStorage)}if(i)for(let a of te("outdated"))a.hidden=!1})}function ks(e,{rx$:t}){let r=(__search==null?void 0:__search.transform)||_i,{searchParams:n}=Oe();n.has("q")&&Ke("search",!0);let o=t.pipe(x(bt),oe(1),m(()=>n.get("q")||""));dt("search").pipe(x(a=>!a),oe(1)).subscribe(()=>{let a=new URL(location.href);a.searchParams.delete("q"),history.replaceState({},"",`${a}`)}),o.subscribe(a=>{a&&(e.value=a,e.focus())});let i=nr(e),s=A(v(e,"keyup"),v(e,"focus").pipe(ke(1)),o).pipe(m(()=>r(e.value)),N(""),B());return Y([s,i]).pipe(m(([a,c])=>({value:a,focus:c})),X(1))}function Ai(e,{tx$:t,rx$:r}){let n=new E,o=n.pipe(de(1));return n.pipe(J("value"),m(({value:i})=>({type:2,data:i}))).subscribe(t.next.bind(t)),n.pipe(J("focus")).subscribe(({focus:i})=>{i?(Ke("search",i),e.placeholder=""):e.placeholder=re("search.placeholder")}),v(e.form,"reset").pipe(ee(o)).subscribe(()=>e.focus()),ks(e,{tx$:t,rx$:r}).pipe(w(i=>n.next(i)),C(()=>n.complete()),m(i=>H({ref:e},i)),ie())}function Ci(e,{rx$:t},{query$:r}){let n=new E,o=Ao(e.parentElement).pipe(x(Boolean)),i=K(":scope > :first-child",e),s=K(":scope > :last-child",e),a=t.pipe(x(bt),oe(1));return n.pipe(ae(r),Mt(a)).subscribe(([{items:f},{value:u}])=>{if(u)switch(f.length){case 0:i.textContent=re("search.result.none");break;case 1:i.textContent=re("search.result.one");break;default:i.textContent=re("search.result.other",lr(f.length))}else i.textContent=re("search.result.placeholder")}),n.pipe(w(()=>s.innerHTML=""),S(({items:f})=>A(I(...f.slice(0,10)),I(...f.slice(10)).pipe(Ce(4),Nr(o),S(([u])=>u))))).subscribe(f=>s.appendChild(Jo(f))),t.pipe(x(vt),m(({data:f})=>f)).pipe(w(f=>n.next(f)),C(()=>n.complete()),m(f=>H({ref:e},f)))}function Hs(e,{query$:t}){return t.pipe(m(({value:r})=>{let n=Oe();return n.hash="",n.searchParams.delete("h"),n.searchParams.set("q",r),{url:n}}))}function Ri(e,t){let r=new E;return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),v(e,"click").subscribe(n=>n.preventDefault()),Hs(e,t).pipe(w(n=>r.next(n)),C(()=>r.complete()),m(n=>H({ref:e},n)))}function ki(e,{rx$:t},{keyboard$:r}){let n=new E,o=_e("search-query"),i=A(v(o,"keydown"),v(o,"focus")).pipe(Le(fe),m(()=>o.value),B());return n.pipe(Ze(i),m(([{suggestions:a},c])=>{let f=c.split(/([\s-]+)/);if((a==null?void 0:a.length)&&f[f.length-1]){let u=a[a.length-1];u.startsWith(f[f.length-1])&&(f[f.length-1]=u)}else f.length=0;return f})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(x(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&o.selectionStart===o.value.length&&(o.value=e.innerText);break}}),t.pipe(x(vt),m(({data:a})=>a)).pipe(w(a=>n.next(a)),C(()=>n.complete()),m(()=>({ref:e})))}function Hi(e,{index$:t,keyboard$:r}){let n=le();try{let o=(__search==null?void 0:__search.worker)||n.search,i=Mi(o,t),s=_e("search-query",e),a=_e("search-result",e),{tx$:c,rx$:f}=i;c.pipe(x(Ti),ut(f.pipe(x(bt))),oe(1)).subscribe(c.next.bind(c)),r.pipe(x(({mode:l})=>l==="search")).subscribe(l=>{let d=Ie();switch(l.type){case"Enter":if(d===s){let h=new Map;for(let b of Q(":first-child [href]",a)){let U=b.firstElementChild;h.set(b,parseFloat(U.getAttribute("data-md-score")))}if(h.size){let[[b]]=[...h].sort(([,U],[,G])=>G-U);b.click()}l.claim()}break;case"Escape":case"Tab":Ke("search",!1),s.blur();break;case"ArrowUp":case"ArrowDown":if(typeof d=="undefined")s.focus();else{let h=[s,...Q(":not(details) > [href], summary, details[open] [href]",a)],b=Math.max(0,(Math.max(0,h.indexOf(d))+h.length+(l.type==="ArrowUp"?-1:1))%h.length);h[b].focus()}l.claim();break;default:s!==Ie()&&s.focus()}}),r.pipe(x(({mode:l})=>l==="global")).subscribe(l=>{switch(l.type){case"f":case"s":case"/":s.focus(),s.select(),l.claim();break}});let u=Ai(s,i),p=Ci(a,i,{query$:u});return A(u,p).pipe(et(...te("search-share",e).map(l=>Ri(l,{query$:u})),...te("search-suggest",e).map(l=>ki(l,i,{keyboard$:r}))))}catch(o){return e.hidden=!0,Se}}function Pi(e,{index$:t,location$:r}){return Y([t,r.pipe(N(Oe()),x(n=>!!n.searchParams.get("h")))]).pipe(m(([n,o])=>rn(n.config,!0)(o.searchParams.get("h"))),m(n=>{var s;let o=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,f=n(c);f.length>c.length&&o.set(a,f)}for(let[a,c]of o){let{childNodes:f}=M("span",null,c);a.replaceWith(...Array.from(f))}return{ref:e,nodes:o}}))}function Ps(e,{viewport$:t,main$:r}){let n=e.parentElement,o=n.offsetTop-n.parentElement.offsetTop;return Y([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(o,Math.max(0,a-i))-o,{height:s,locked:a>=i+o})),B((i,s)=>i.height===s.height&&i.locked===s.locked))}function nn(e,n){var o=n,{header$:t}=o,r=un(o,["header$"]);let i=K(".md-sidebar__scrollwrap",e),{y:s}=qe(i);return P(()=>{let a=new E;return a.pipe(Ae(0,xe),ae(t)).subscribe({next([{height:c},{height:f}]){i.style.height=`${c-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),a.pipe(Le(xe),oe(1)).subscribe(()=>{for(let c of Q(".md-nav__link--active[href]",e)){let f=cr(c);if(typeof f!="undefined"){let u=c.offsetTop-f.offsetTop,{height:p}=he(f);f.scrollTo({top:u-p/2})}}}),Ps(e,r).pipe(w(c=>a.next(c)),C(()=>a.complete()),m(c=>H({ref:e},c)))})}function $i(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return _t(je(`${r}/releases/latest`).pipe(ce(()=>R),m(n=>({version:n.tag_name})),De({})),je(r).pipe(ce(()=>R),m(n=>({stars:n.stargazers_count,forks:n.forks_count})),De({}))).pipe(m(([n,o])=>H(H({},n),o)))}else{let r=`https://api.github.com/users/${e}`;return je(r).pipe(m(n=>({repositories:n.public_repos})),De({}))}}function Ii(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return je(r).pipe(ce(()=>R),m(({star_count:n,forks_count:o})=>({stars:n,forks:o})),De({}))}function ji(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,n]=t;return $i(r,n)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,n]=t;return Ii(r,n)}return R}var $s;function Is(e){return $s||($s=P(()=>{let t=__md_get("__source",sessionStorage);if(t)return I(t);if(te("consent").length){let n=__md_get("__consent");if(!(n&&n.github))return R}return ji(e.href).pipe(w(n=>__md_set("__source",n,sessionStorage)))}).pipe(ce(()=>R),x(t=>Object.keys(t).length>0),m(t=>({facts:t})),X(1)))}function Fi(e){let t=K(":scope > :last-child",e);return P(()=>{let r=new E;return r.subscribe(({facts:n})=>{t.appendChild(Xo(n)),t.classList.add("md-source__repository--active")}),Is(e).pipe(w(n=>r.next(n)),C(()=>r.complete()),m(n=>H({ref:e},n)))})}function js(e,{viewport$:t,header$:r}){return ve(document.body).pipe(S(()=>dr(e,{header$:r,viewport$:t})),m(({offset:{y:n}})=>({hidden:n>=10})),J("hidden"))}function Ui(e,t){return P(()=>{let r=new E;return r.subscribe({next({hidden:n}){e.hidden=n},complete(){e.hidden=!1}}),(Z("navigation.tabs.sticky")?I({hidden:!1}):js(e,t)).pipe(w(n=>r.next(n)),C(()=>r.complete()),m(n=>H({ref:e},n)))})}function Fs(e,{viewport$:t,header$:r}){let n=new Map,o=Q("[href^=\\#]",e);for(let a of o){let c=decodeURIComponent(a.hash.substring(1)),f=pe(`[id="${c}"]`);typeof f!="undefined"&&n.set(a,f)}let i=r.pipe(J("height"),m(({height:a})=>{let c=_e("main"),f=K(":scope > :first-child",c);return a+.8*(f.offsetTop-c.offsetTop)}),ie());return ve(document.body).pipe(J("height"),S(a=>P(()=>{let c=[];return I([...n].reduce((f,[u,p])=>{for(;c.length&&n.get(c[c.length-1]).tagName>=p.tagName;)c.pop();let l=p.offsetTop;for(;!l&&p.parentElement;)p=p.parentElement,l=p.offsetTop;return f.set([...c=[...c,u]].reverse(),l)},new Map))}).pipe(m(c=>new Map([...c].sort(([,f],[,u])=>f-u))),Ze(i),S(([c,f])=>t.pipe(Ur(([u,p],{offset:{y:l},size:d})=>{let h=l+d.height>=Math.floor(a.height);for(;p.length;){let[,b]=p[0];if(b-f=l&&!h)p=[u.pop(),...p];else break}return[u,p]},[[],[...c]]),B((u,p)=>u[0]===p[0]&&u[1]===p[1])))))).pipe(m(([a,c])=>({prev:a.map(([f])=>f),next:c.map(([f])=>f)})),N({prev:[],next:[]}),Ce(2,1),m(([a,c])=>a.prev.length{let o=new E,i=o.pipe(de(1));if(o.subscribe(({prev:s,next:a})=>{for(let[c]of a)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[f]]of s.entries())f.classList.add("md-nav__link--passed"),f.classList.toggle("md-nav__link--active",c===s.length-1)}),Z("toc.follow")){let s=A(t.pipe(Re(1),m(()=>{})),t.pipe(Re(250),m(()=>"smooth")));o.pipe(x(({prev:a})=>a.length>0),ae(s)).subscribe(([{prev:a},c])=>{let[f]=a[a.length-1];if(f.offsetHeight){let u=cr(f);if(typeof u!="undefined"){let p=f.offsetTop-u.offsetTop,{height:l}=he(u);u.scrollTo({top:p-l/2,behavior:c})}}})}return Z("navigation.tracking")&&t.pipe(ee(i),J("offset"),Re(250),He(1),ee(n.pipe(He(1))),Tt({delay:250}),ae(o)).subscribe(([,{prev:s}])=>{let a=Oe(),c=s[s.length-1];if(c&&c.length){let[f]=c,{hash:u}=new URL(f.href);a.hash!==u&&(a.hash=u,history.replaceState({},"",`${a}`))}else a.hash="",history.replaceState({},"",`${a}`)}),Fs(e,{viewport$:t,header$:r}).pipe(w(s=>o.next(s)),C(()=>o.complete()),m(s=>H({ref:e},s)))})}function Us(e,{viewport$:t,main$:r,target$:n}){let o=t.pipe(m(({offset:{y:s}})=>s),Ce(2,1),m(([s,a])=>s>a&&a>0),B()),i=r.pipe(m(({active:s})=>s));return Y([i,o]).pipe(m(([s,a])=>!(s&&a)),B(),ee(n.pipe(He(1))),Fr(!0),Tt({delay:250}),m(s=>({hidden:s})))}function Wi(e,{viewport$:t,header$:r,main$:n,target$:o}){let i=new E,s=i.pipe(de(1));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(ee(s),J("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),Us(e,{viewport$:t,main$:n,target$:o}).pipe(w(a=>i.next(a)),C(()=>i.complete()),m(a=>H({ref:e},a)))}function Vi({document$:e,tablet$:t}){e.pipe(S(()=>Q(".md-toggle--indeterminate, [data-md-state=indeterminate]")),w(r=>{r.indeterminate=!0,r.checked=!1}),se(r=>v(r,"change").pipe(Wr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ae(t)).subscribe(([r,n])=>{r.classList.remove("md-toggle--indeterminate"),n&&(r.checked=!1)})}function Ds(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function zi({document$:e}){e.pipe(S(()=>Q("[data-md-scrollfix]")),w(t=>t.removeAttribute("data-md-scrollfix")),x(Ds),se(t=>v(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ni({viewport$:e,tablet$:t}){Y([dt("search"),t]).pipe(m(([r,n])=>r&&!n),S(r=>I(r).pipe(ke(r?400:100))),ae(e)).subscribe(([r,{offset:{y:n}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${n}px`;else{let o=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",o&&window.scrollTo(0,o)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let n=e[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?t.insertBefore(this.previousSibling,n):t.replaceChild(n,this)}}}));document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var tt=go(),vr=ko(),gt=jo(),on=Ro(),we=qo(),gr=Kr("(min-width: 960px)"),Ki=Kr("(min-width: 1220px)"),Qi=Fo(),Yi=le(),Bi=document.forms.namedItem("search")?(__search==null?void 0:__search.index)||je(new URL("search/search_index.json",Yi.base)):Se,an=new E;wi({alert$:an});Z("navigation.instant")&&Ei({document$:tt,location$:vr,viewport$:we});var qi;((qi=Yi.version)==null?void 0:qi.provider)==="mike"&&Li({document$:tt});A(vr,gt).pipe(ke(125)).subscribe(()=>{Ke("drawer",!1),Ke("search",!1)});on.pipe(x(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=pe("[href][rel=prev]");typeof t!="undefined"&&t.click();break;case"n":case".":let r=pe("[href][rel=next]");typeof r!="undefined"&&r.click();break}});Vi({document$:tt,tablet$:gr});zi({document$:tt});Ni({viewport$:we,tablet$:gr});var Qe=bi(_e("header"),{viewport$:we}),br=tt.pipe(m(()=>_e("main")),S(e=>yi(e,{viewport$:we,header$:Qe})),X(1)),Ws=A(...te("consent").map(e=>Yo(e,{target$:gt})),...te("dialog").map(e=>hi(e,{alert$:an})),...te("header").map(e=>vi(e,{viewport$:we,header$:Qe,main$:br})),...te("palette").map(e=>xi(e)),...te("search").map(e=>Hi(e,{index$:Bi,keyboard$:on})),...te("source").map(e=>Fi(e))),Vs=P(()=>A(...te("announce").map(e=>Qo(e)),...te("content").map(e=>di(e,{viewport$:we,target$:gt,print$:Qi})),...te("content").map(e=>Z("search.highlight")?Pi(e,{index$:Bi,location$:vr}):R),...te("header-title").map(e=>gi(e,{viewport$:we,header$:Qe})),...te("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Qr(Ki,()=>nn(e,{viewport$:we,header$:Qe,main$:br})):Qr(gr,()=>nn(e,{viewport$:we,header$:Qe,main$:br}))),...te("tabs").map(e=>Ui(e,{viewport$:we,header$:Qe})),...te("toc").map(e=>Di(e,{viewport$:we,header$:Qe,target$:gt})),...te("top").map(e=>Wi(e,{viewport$:we,header$:Qe,main$:br,target$:gt})))),Gi=tt.pipe(S(()=>Vs),et(Ws),X(1));Gi.subscribe();window.document$=tt;window.location$=vr;window.target$=gt;window.keyboard$=on;window.viewport$=we;window.tablet$=gr;window.screen$=Ki;window.print$=Qi;window.alert$=an;window.component$=Gi;})(); +//# sourceMappingURL=bundle.5a2dcb6a.min.js.map + diff --git a/assets/javascripts/bundle.5a2dcb6a.min.js.map b/assets/javascripts/bundle.5a2dcb6a.min.js.map new file mode 100644 index 000000000..34e26a3ad --- /dev/null +++ b/assets/javascripts/bundle.5a2dcb6a.min.js.map @@ -0,0 +1,8 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/url-polyfill/url-polyfill.js", "node_modules/rxjs/node_modules/tslib/tslib.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "node_modules/array-flat-polyfill/index.mjs", "src/assets/javascripts/bundle.ts", "node_modules/unfetch/polyfill/index.js", "node_modules/rxjs/node_modules/tslib/modules/index.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/concatMap.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/sample.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/assets/javascripts/browser/document/index.ts", "src/assets/javascripts/browser/element/_/index.ts", "src/assets/javascripts/browser/element/focus/index.ts", "src/assets/javascripts/browser/element/offset/_/index.ts", "src/assets/javascripts/browser/element/offset/content/index.ts", "node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js", "src/assets/javascripts/browser/element/size/_/index.ts", "src/assets/javascripts/browser/element/size/content/index.ts", "src/assets/javascripts/browser/element/visibility/index.ts", "src/assets/javascripts/browser/toggle/index.ts", "src/assets/javascripts/browser/keyboard/index.ts", "src/assets/javascripts/browser/location/_/index.ts", "src/assets/javascripts/utilities/h/index.ts", "src/assets/javascripts/utilities/string/index.ts", "src/assets/javascripts/browser/location/hash/index.ts", "src/assets/javascripts/browser/media/index.ts", "src/assets/javascripts/browser/request/index.ts", "src/assets/javascripts/browser/script/index.ts", "src/assets/javascripts/browser/viewport/offset/index.ts", "src/assets/javascripts/browser/viewport/size/index.ts", "src/assets/javascripts/browser/viewport/_/index.ts", "src/assets/javascripts/browser/viewport/at/index.ts", "src/assets/javascripts/browser/worker/index.ts", "src/assets/javascripts/_/index.ts", "src/assets/javascripts/components/_/index.ts", "src/assets/javascripts/components/announce/index.ts", "src/assets/javascripts/components/consent/index.ts", "src/assets/javascripts/components/content/code/_/index.ts", "src/assets/javascripts/templates/tooltip/index.tsx", "src/assets/javascripts/templates/annotation/index.tsx", "src/assets/javascripts/templates/clipboard/index.tsx", "src/assets/javascripts/templates/search/index.tsx", "src/assets/javascripts/templates/source/index.tsx", "src/assets/javascripts/templates/tabbed/index.tsx", "src/assets/javascripts/templates/table/index.tsx", "src/assets/javascripts/templates/version/index.tsx", "src/assets/javascripts/components/content/annotation/_/index.ts", "src/assets/javascripts/components/content/annotation/list/index.ts", "src/assets/javascripts/components/content/code/mermaid/index.ts", "src/assets/javascripts/components/content/details/index.ts", "src/assets/javascripts/components/content/table/index.ts", "src/assets/javascripts/components/content/tabs/index.ts", "src/assets/javascripts/components/content/_/index.ts", "src/assets/javascripts/components/dialog/index.ts", "src/assets/javascripts/components/header/_/index.ts", "src/assets/javascripts/components/header/title/index.ts", "src/assets/javascripts/components/main/index.ts", "src/assets/javascripts/components/palette/index.ts", "src/assets/javascripts/integrations/clipboard/index.ts", "src/assets/javascripts/integrations/sitemap/index.ts", "src/assets/javascripts/integrations/instant/index.ts", "src/assets/javascripts/integrations/search/document/index.ts", "src/assets/javascripts/integrations/search/highlighter/index.ts", "src/assets/javascripts/integrations/search/query/transform/index.ts", "src/assets/javascripts/integrations/search/worker/message/index.ts", "src/assets/javascripts/integrations/search/worker/_/index.ts", "src/assets/javascripts/integrations/version/index.ts", "src/assets/javascripts/components/search/query/index.ts", "src/assets/javascripts/components/search/result/index.ts", "src/assets/javascripts/components/search/share/index.ts", "src/assets/javascripts/components/search/suggest/index.ts", "src/assets/javascripts/components/search/_/index.ts", "src/assets/javascripts/components/search/highlight/index.ts", "src/assets/javascripts/components/sidebar/index.ts", "src/assets/javascripts/components/source/facts/github/index.ts", "src/assets/javascripts/components/source/facts/gitlab/index.ts", "src/assets/javascripts/components/source/facts/_/index.ts", "src/assets/javascripts/components/source/_/index.ts", "src/assets/javascripts/components/tabs/index.ts", "src/assets/javascripts/components/toc/index.ts", "src/assets/javascripts/components/top/index.ts", "src/assets/javascripts/patches/indeterminate/index.ts", "src/assets/javascripts/patches/scrollfix/index.ts", "src/assets/javascripts/patches/scrolllock/index.ts", "src/assets/javascripts/polyfills/index.ts"], + "sourceRoot": "../../../..", + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "(function(global) {\r\n /**\r\n * Polyfill URLSearchParams\r\n *\r\n * Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js\r\n */\r\n\r\n var checkIfIteratorIsSupported = function() {\r\n try {\r\n return !!Symbol.iterator;\r\n } catch (error) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var iteratorSupported = checkIfIteratorIsSupported();\r\n\r\n var createIterator = function(items) {\r\n var iterator = {\r\n next: function() {\r\n var value = items.shift();\r\n return { done: value === void 0, value: value };\r\n }\r\n };\r\n\r\n if (iteratorSupported) {\r\n iterator[Symbol.iterator] = function() {\r\n return iterator;\r\n };\r\n }\r\n\r\n return iterator;\r\n };\r\n\r\n /**\r\n * Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing\r\n * encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.\r\n */\r\n var serializeParam = function(value) {\r\n return encodeURIComponent(value).replace(/%20/g, '+');\r\n };\r\n\r\n var deserializeParam = function(value) {\r\n return decodeURIComponent(String(value).replace(/\\+/g, ' '));\r\n };\r\n\r\n var polyfillURLSearchParams = function() {\r\n\r\n var URLSearchParams = function(searchString) {\r\n Object.defineProperty(this, '_entries', { writable: true, value: {} });\r\n var typeofSearchString = typeof searchString;\r\n\r\n if (typeofSearchString === 'undefined') {\r\n // do nothing\r\n } else if (typeofSearchString === 'string') {\r\n if (searchString !== '') {\r\n this._fromString(searchString);\r\n }\r\n } else if (searchString instanceof URLSearchParams) {\r\n var _this = this;\r\n searchString.forEach(function(value, name) {\r\n _this.append(name, value);\r\n });\r\n } else if ((searchString !== null) && (typeofSearchString === 'object')) {\r\n if (Object.prototype.toString.call(searchString) === '[object Array]') {\r\n for (var i = 0; i < searchString.length; i++) {\r\n var entry = searchString[i];\r\n if ((Object.prototype.toString.call(entry) === '[object Array]') || (entry.length !== 2)) {\r\n this.append(entry[0], entry[1]);\r\n } else {\r\n throw new TypeError('Expected [string, any] as entry at index ' + i + ' of URLSearchParams\\'s input');\r\n }\r\n }\r\n } else {\r\n for (var key in searchString) {\r\n if (searchString.hasOwnProperty(key)) {\r\n this.append(key, searchString[key]);\r\n }\r\n }\r\n }\r\n } else {\r\n throw new TypeError('Unsupported input\\'s type for URLSearchParams');\r\n }\r\n };\r\n\r\n var proto = URLSearchParams.prototype;\r\n\r\n proto.append = function(name, value) {\r\n if (name in this._entries) {\r\n this._entries[name].push(String(value));\r\n } else {\r\n this._entries[name] = [String(value)];\r\n }\r\n };\r\n\r\n proto.delete = function(name) {\r\n delete this._entries[name];\r\n };\r\n\r\n proto.get = function(name) {\r\n return (name in this._entries) ? this._entries[name][0] : null;\r\n };\r\n\r\n proto.getAll = function(name) {\r\n return (name in this._entries) ? this._entries[name].slice(0) : [];\r\n };\r\n\r\n proto.has = function(name) {\r\n return (name in this._entries);\r\n };\r\n\r\n proto.set = function(name, value) {\r\n this._entries[name] = [String(value)];\r\n };\r\n\r\n proto.forEach = function(callback, thisArg) {\r\n var entries;\r\n for (var name in this._entries) {\r\n if (this._entries.hasOwnProperty(name)) {\r\n entries = this._entries[name];\r\n for (var i = 0; i < entries.length; i++) {\r\n callback.call(thisArg, entries[i], name, this);\r\n }\r\n }\r\n }\r\n };\r\n\r\n proto.keys = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push(name);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.values = function() {\r\n var items = [];\r\n this.forEach(function(value) {\r\n items.push(value);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n proto.entries = function() {\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n });\r\n return createIterator(items);\r\n };\r\n\r\n if (iteratorSupported) {\r\n proto[Symbol.iterator] = proto.entries;\r\n }\r\n\r\n proto.toString = function() {\r\n var searchArray = [];\r\n this.forEach(function(value, name) {\r\n searchArray.push(serializeParam(name) + '=' + serializeParam(value));\r\n });\r\n return searchArray.join('&');\r\n };\r\n\r\n\r\n global.URLSearchParams = URLSearchParams;\r\n };\r\n\r\n var checkIfURLSearchParamsSupported = function() {\r\n try {\r\n var URLSearchParams = global.URLSearchParams;\r\n\r\n return (\r\n (new URLSearchParams('?a=1').toString() === 'a=1') &&\r\n (typeof URLSearchParams.prototype.set === 'function') &&\r\n (typeof URLSearchParams.prototype.entries === 'function')\r\n );\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n if (!checkIfURLSearchParamsSupported()) {\r\n polyfillURLSearchParams();\r\n }\r\n\r\n var proto = global.URLSearchParams.prototype;\r\n\r\n if (typeof proto.sort !== 'function') {\r\n proto.sort = function() {\r\n var _this = this;\r\n var items = [];\r\n this.forEach(function(value, name) {\r\n items.push([name, value]);\r\n if (!_this._entries) {\r\n _this.delete(name);\r\n }\r\n });\r\n items.sort(function(a, b) {\r\n if (a[0] < b[0]) {\r\n return -1;\r\n } else if (a[0] > b[0]) {\r\n return +1;\r\n } else {\r\n return 0;\r\n }\r\n });\r\n if (_this._entries) { // force reset because IE keeps keys index\r\n _this._entries = {};\r\n }\r\n for (var i = 0; i < items.length; i++) {\r\n this.append(items[i][0], items[i][1]);\r\n }\r\n };\r\n }\r\n\r\n if (typeof proto._fromString !== 'function') {\r\n Object.defineProperty(proto, '_fromString', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function(searchString) {\r\n if (this._entries) {\r\n this._entries = {};\r\n } else {\r\n var keys = [];\r\n this.forEach(function(value, name) {\r\n keys.push(name);\r\n });\r\n for (var i = 0; i < keys.length; i++) {\r\n this.delete(keys[i]);\r\n }\r\n }\r\n\r\n searchString = searchString.replace(/^\\?/, '');\r\n var attributes = searchString.split('&');\r\n var attribute;\r\n for (var i = 0; i < attributes.length; i++) {\r\n attribute = attributes[i].split('=');\r\n this.append(\r\n deserializeParam(attribute[0]),\r\n (attribute.length > 1) ? deserializeParam(attribute[1]) : ''\r\n );\r\n }\r\n }\r\n });\r\n }\r\n\r\n // HTMLAnchorElement\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n\r\n(function(global) {\r\n /**\r\n * Polyfill URL\r\n *\r\n * Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js\r\n */\r\n\r\n var checkIfURLIsSupported = function() {\r\n try {\r\n var u = new global.URL('b', 'http://a');\r\n u.pathname = 'c d';\r\n return (u.href === 'http://a/c%20d') && u.searchParams;\r\n } catch (e) {\r\n return false;\r\n }\r\n };\r\n\r\n\r\n var polyfillURL = function() {\r\n var _URL = global.URL;\r\n\r\n var URL = function(url, base) {\r\n if (typeof url !== 'string') url = String(url);\r\n if (base && typeof base !== 'string') base = String(base);\r\n\r\n // Only create another document if the base is different from current location.\r\n var doc = document, baseElement;\r\n if (base && (global.location === void 0 || base !== global.location.href)) {\r\n base = base.toLowerCase();\r\n doc = document.implementation.createHTMLDocument('');\r\n baseElement = doc.createElement('base');\r\n baseElement.href = base;\r\n doc.head.appendChild(baseElement);\r\n try {\r\n if (baseElement.href.indexOf(base) !== 0) throw new Error(baseElement.href);\r\n } catch (err) {\r\n throw new Error('URL unable to set base ' + base + ' due to ' + err);\r\n }\r\n }\r\n\r\n var anchorElement = doc.createElement('a');\r\n anchorElement.href = url;\r\n if (baseElement) {\r\n doc.body.appendChild(anchorElement);\r\n anchorElement.href = anchorElement.href; // force href to refresh\r\n }\r\n\r\n var inputElement = doc.createElement('input');\r\n inputElement.type = 'url';\r\n inputElement.value = url;\r\n\r\n if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || (!inputElement.checkValidity() && !base)) {\r\n throw new TypeError('Invalid URL');\r\n }\r\n\r\n Object.defineProperty(this, '_anchorElement', {\r\n value: anchorElement\r\n });\r\n\r\n\r\n // create a linked searchParams which reflect its changes on URL\r\n var searchParams = new global.URLSearchParams(this.search);\r\n var enableSearchUpdate = true;\r\n var enableSearchParamsUpdate = true;\r\n var _this = this;\r\n ['append', 'delete', 'set'].forEach(function(methodName) {\r\n var method = searchParams[methodName];\r\n searchParams[methodName] = function() {\r\n method.apply(searchParams, arguments);\r\n if (enableSearchUpdate) {\r\n enableSearchParamsUpdate = false;\r\n _this.search = searchParams.toString();\r\n enableSearchParamsUpdate = true;\r\n }\r\n };\r\n });\r\n\r\n Object.defineProperty(this, 'searchParams', {\r\n value: searchParams,\r\n enumerable: true\r\n });\r\n\r\n var search = void 0;\r\n Object.defineProperty(this, '_updateSearchParams', {\r\n enumerable: false,\r\n configurable: false,\r\n writable: false,\r\n value: function() {\r\n if (this.search !== search) {\r\n search = this.search;\r\n if (enableSearchParamsUpdate) {\r\n enableSearchUpdate = false;\r\n this.searchParams._fromString(this.search);\r\n enableSearchUpdate = true;\r\n }\r\n }\r\n }\r\n });\r\n };\r\n\r\n var proto = URL.prototype;\r\n\r\n var linkURLWithAnchorAttribute = function(attributeName) {\r\n Object.defineProperty(proto, attributeName, {\r\n get: function() {\r\n return this._anchorElement[attributeName];\r\n },\r\n set: function(value) {\r\n this._anchorElement[attributeName] = value;\r\n },\r\n enumerable: true\r\n });\r\n };\r\n\r\n ['hash', 'host', 'hostname', 'port', 'protocol']\r\n .forEach(function(attributeName) {\r\n linkURLWithAnchorAttribute(attributeName);\r\n });\r\n\r\n Object.defineProperty(proto, 'search', {\r\n get: function() {\r\n return this._anchorElement['search'];\r\n },\r\n set: function(value) {\r\n this._anchorElement['search'] = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n });\r\n\r\n Object.defineProperties(proto, {\r\n\r\n 'toString': {\r\n get: function() {\r\n var _this = this;\r\n return function() {\r\n return _this.href;\r\n };\r\n }\r\n },\r\n\r\n 'href': {\r\n get: function() {\r\n return this._anchorElement.href.replace(/\\?$/, '');\r\n },\r\n set: function(value) {\r\n this._anchorElement.href = value;\r\n this._updateSearchParams();\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'pathname': {\r\n get: function() {\r\n return this._anchorElement.pathname.replace(/(^\\/?)/, '/');\r\n },\r\n set: function(value) {\r\n this._anchorElement.pathname = value;\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'origin': {\r\n get: function() {\r\n // get expected port from protocol\r\n var expectedPort = { 'http:': 80, 'https:': 443, 'ftp:': 21 }[this._anchorElement.protocol];\r\n // add port to origin if, expected port is different than actual port\r\n // and it is not empty f.e http://foo:8080\r\n // 8080 != 80 && 8080 != ''\r\n var addPortToOrigin = this._anchorElement.port != expectedPort &&\r\n this._anchorElement.port !== '';\r\n\r\n return this._anchorElement.protocol +\r\n '//' +\r\n this._anchorElement.hostname +\r\n (addPortToOrigin ? (':' + this._anchorElement.port) : '');\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'password': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n\r\n 'username': { // TODO\r\n get: function() {\r\n return '';\r\n },\r\n set: function(value) {\r\n },\r\n enumerable: true\r\n },\r\n });\r\n\r\n URL.createObjectURL = function(blob) {\r\n return _URL.createObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n URL.revokeObjectURL = function(url) {\r\n return _URL.revokeObjectURL.apply(_URL, arguments);\r\n };\r\n\r\n global.URL = URL;\r\n\r\n };\r\n\r\n if (!checkIfURLIsSupported()) {\r\n polyfillURL();\r\n }\r\n\r\n if ((global.location !== void 0) && !('origin' in global.location)) {\r\n var getOrigin = function() {\r\n return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');\r\n };\r\n\r\n try {\r\n Object.defineProperty(global.location, 'origin', {\r\n get: getOrigin,\r\n enumerable: true\r\n });\r\n } catch (e) {\r\n setInterval(function() {\r\n global.location.origin = getOrigin();\r\n }, 100);\r\n }\r\n }\r\n\r\n})(\r\n (typeof global !== 'undefined') ? global\r\n : ((typeof window !== 'undefined') ? window\r\n : ((typeof self !== 'undefined') ? self : this))\r\n);\r\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __spreadArrays;\r\nvar __spreadArray;\r\nvar __await;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\nvar __makeTemplateObject;\r\nvar __importStar;\r\nvar __importDefault;\r\nvar __classPrivateFieldGet;\r\nvar __classPrivateFieldSet;\r\nvar __createBinding;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n if (exports !== root) {\r\n if (typeof Object.create === \"function\") {\r\n Object.defineProperty(exports, \"__esModule\", { value: true });\r\n }\r\n else {\r\n exports.__esModule = true;\r\n }\r\n }\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n };\r\n\r\n __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n }) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n });\r\n\r\n __values = function (o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spreadArrays = function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n };\r\n\r\n __spreadArray = function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n };\r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n };\r\n\r\n __makeTemplateObject = function (cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n };\r\n\r\n var __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n }) : function(o, v) {\r\n o[\"default\"] = v;\r\n };\r\n\r\n __importStar = function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n };\r\n\r\n __importDefault = function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n };\r\n\r\n __classPrivateFieldGet = function (receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n };\r\n\r\n __classPrivateFieldSet = function (receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__createBinding\", __createBinding);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__spreadArrays\", __spreadArrays);\r\n exporter(\"__spreadArray\", __spreadArray);\r\n exporter(\"__await\", __await);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n exporter(\"__makeTemplateObject\", __makeTemplateObject);\r\n exporter(\"__importStar\", __importStar);\r\n exporter(\"__importDefault\", __importDefault);\r\n exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\r\n exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\r\n});\r\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "Array.prototype.flat||Object.defineProperty(Array.prototype,\"flat\",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,function(a,e){return Array.isArray(e)?a.push.apply(a,r.call(e,t-1)):a.push(e),a},[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,\"flatMap\",{configurable:!0,value:function(r){return Array.prototype.map.apply(this,arguments).flat()},writable:!0})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"array-flat-polyfill\"\nimport \"focus-visible\"\nimport \"unfetch/polyfill\"\nimport \"url-polyfill\"\n\nimport {\n EMPTY,\n NEVER,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getOptionalElement,\n requestJSON,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantLoading,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget()\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? __search?.index || requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up instant loading, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantLoading({ document$, location$, viewport$ })\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"[href][rel=prev]\")\n if (typeof prev !== \"undefined\")\n prev.click()\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, { viewport$, header$, target$ })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.component$ = component$ /* Component observable */\n", "self.fetch||(self.fetch=function(e,n){return n=n||{},new Promise(function(t,s){var r=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(r.status/100|0),statusText:r.statusText,status:r.status,url:r.responseURL,text:function(){return Promise.resolve(r.responseText)},json:function(){return Promise.resolve(r.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([r.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var c in r.open(n.method||\"get\",e,!0),r.onload=function(){r.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm,function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+\",\"+t:t}),t(a())},r.onerror=s,r.withCredentials=\"include\"==n.credentials,n.headers)r.setRequestHeader(c,n.headers[c]);r.send(n.body||null)})});\n", "import tslib from '../tslib.js';\r\nconst {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n} = tslib;\r\nexport {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n};\r\n", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ReplaySubject,\n Subject,\n fromEvent\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents are implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted.\n *\n * @returns Document subject\n */\nexport function watchDocument(): Subject {\n const document$ = new ReplaySubject(1)\n fromEvent(document, \"DOMContentLoaded\", { once: true })\n .subscribe(() => document$.next(document))\n\n /* Return document */\n return document$\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve all elements matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getElements(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T][]\n\nexport function getElements(\n selector: string, node?: ParentNode\n): T[]\n\nexport function getElements(\n selector: string, node: ParentNode = document\n): T[] {\n return Array.from(node.querySelectorAll(selector))\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\n *\n * Note that this function assumes that the element is present. If unsure if an\n * element is existent, use the `getOptionalElement` function instead.\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T]\n\nexport function getElement(\n selector: string, node?: ParentNode\n): T\n\nexport function getElement(\n selector: string, node: ParentNode = document\n): T {\n const el = getOptionalElement(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n\n /* Return element */\n return el\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Retrieve an optional element matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @returns Element or nothing\n */\nexport function getOptionalElement(\n selector: T, node?: ParentNode\n): HTMLElementTagNameMap[T] | undefined\n\nexport function getOptionalElement(\n selector: string, node?: ParentNode\n): T | undefined\n\nexport function getOptionalElement(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector(selector) || undefined\n}\n\n/**\n * Retrieve the currently active element\n *\n * @returns Element or nothing\n */\nexport function getActiveElement(): HTMLElement | undefined {\n return document.activeElement instanceof HTMLElement\n ? document.activeElement || undefined\n : undefined\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n debounceTime,\n distinctUntilChanged,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\n *\n * Previously, this function used `focus` and `blur` events to determine whether\n * an element is focused, but this doesn't work if there are focusable elements\n * within the elements itself. A better solutions are `focusin` and `focusout`\n * events, which bubble up the tree and allow for more fine-grained control.\n *\n * `debounceTime` is necessary, because when a focus change happens inside an\n * element, the observable would first emit `false` and then `true` again.\n *\n * @param el - Element\n *\n * @returns Element focus observable\n */\nexport function watchElementFocus(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(document.body, \"focusin\"),\n fromEvent(document.body, \"focusout\")\n )\n .pipe(\n debounceTime(1),\n map(() => {\n const active = getActiveElement()\n return typeof active !== \"undefined\"\n ? el.contains(active)\n : false\n }),\n startWith(el === getActiveElement()),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element offset\n *\n * @param el - Element\n *\n * @returns Element offset\n */\nexport function getElementOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.offsetLeft,\n y: el.offsetTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element offset\n *\n * @param el - Element\n *\n * @returns Element offset observable\n */\nexport function watchElementOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(window, \"load\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n animationFrameScheduler,\n auditTime,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\nimport { ElementOffset } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content offset (= scroll offset)\n *\n * @param el - Element\n *\n * @returns Element content offset\n */\nexport function getElementContentOffset(\n el: HTMLElement\n): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element content offset\n *\n * @param el - Element\n *\n * @returns Element content offset observable\n */\nexport function watchElementContentOffset(\n el: HTMLElement\n): Observable {\n return merge(\n fromEvent(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n auditTime(0, animationFrameScheduler),\n map(() => getElementContentOffset(el)),\n startWith(getElementContentOffset(el))\n )\n}\n", "/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== 'undefined') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, \"size\", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof global !== 'undefined' && global.Math === Math) {\r\n return global;\r\n }\r\n if (typeof self !== 'undefined' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== 'undefined' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function('return this')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === 'function') {\r\n // It's required to use a bounded function because IE sometimes throws\r\n // an \"Invalid calling object\" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the \"proxy\" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for \"transitions\" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== 'undefined';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven't been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it's present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns \"true\" if any observer has detected changes in\r\n * dimensions of it's elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the \"Transitionend\" event is used as a workaround for\r\n // delayed transitions. This way it's possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener('transitionend', this.onTransitionEnd_);\r\n window.addEventListener('resize', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener('DOMSubtreeModified', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener('transitionend', this.onTransitionEnd_);\r\n window.removeEventListener('resize', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener('DOMSubtreeModified', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * \"Transitionend\" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller's instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the \"ownerDocument\" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it's not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles['border-' + position + '-width'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = ['top', 'right', 'bottom', 'left'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles['padding-' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can't be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it's not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery's ':visible' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it's data wasn't\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the 'border-box' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === 'border-box') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn't include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the \"client\"\r\n // properties then it's either IE, and thus we don't need to subtract\r\n // anything, or an element merely doesn't have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, 'left', 'right') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, 'top', 'bottom') + vertPad;\r\n }\r\n }\r\n // Following steps can't be applied to the document's root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it's as well not necessary as the itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and \"client\" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of \"client\" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn't happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== 'undefined') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it's so, then check that element is at least an instance of the\r\n // SVGElement and that it has the \"getBBox\" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === 'function'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element ().\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle's properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle's width.\r\n * @param {number} height - Rectangle's height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it's changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it's width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element's content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they'd require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don't support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it's content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== 'function') {\r\n throw new TypeError('The callback provided as parameter 1 is not a function.');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n // Do nothing if current environment doesn't have the Element interface.\r\n if (typeof Element === 'undefined' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError('parameter 1 is not of type \"Element\".');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it's content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn't have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can't be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError('Cannot call a class as a function.');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError('1 argument required, but only 0 present.');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n 'observe',\r\n 'unobserve',\r\n 'disconnect'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== 'undefined') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\nexport default index;\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ResizeObserver from \"resize-observer-polyfill\"\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementSize {\n width: number /* Element width */\n height: number /* Element height */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Resize observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Resize observer observable\n *\n * This observable will create a `ResizeObserver` on the first subscription\n * and will automatically terminate it when there are no more subscribers.\n * It's quite important to centralize observation in a single `ResizeObserver`,\n * as the performance difference can be quite dramatic, as the link shows.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new ResizeObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @returns Element size\n */\nexport function getElementSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that subscribes to a single internal\n * instance of `ResizeObserver` upon subscription, and emit resize events until\n * termination. Note that this function should not be called with the same\n * element twice, as the first unsubscription will terminate observation.\n *\n * Sadly, we can't use the `DOMRect` objects returned by the observer, because\n * we need the emitted values to be consistent with `getElementSize`, which will\n * return the used values (rounded) and not actual values (unrounded). Thus, we\n * use the `offset*` properties. See the linked GitHub issue.\n *\n * @see https://bit.ly/3m0k3he - GitHub issue\n *\n * @param el - Element\n *\n * @returns Element size observable\n */\nexport function watchElementSize(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(() => getElementSize(el))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ElementSize } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element content size (= scroll width and height)\n *\n * @param el - Element\n *\n * @returns Element content size\n */\nexport function getElementContentSize(\n el: HTMLElement\n): ElementSize {\n return {\n width: el.scrollWidth,\n height: el.scrollHeight\n }\n}\n\n/**\n * Retrieve the overflowing container of an element, if any\n *\n * @param el - Element\n *\n * @returns Overflowing container or nothing\n */\nexport function getElementContainer(\n el: HTMLElement\n): HTMLElement | undefined {\n let parent = el.parentElement\n while (parent)\n if (\n el.scrollWidth <= parent.scrollWidth &&\n el.scrollHeight <= parent.scrollHeight\n )\n parent = (el = parent).parentElement\n else\n break\n\n /* Return overflowing container */\n return parent ? el : undefined\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n filter,\n finalize,\n map,\n merge,\n of,\n shareReplay,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport {\n getElementContentSize,\n getElementSize,\n watchElementContentOffset\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Intersection observer entry subject\n */\nconst entry$ = new Subject()\n\n/**\n * Intersection observer observable\n *\n * This observable will create an `IntersectionObserver` on first subscription\n * and will automatically terminate it when there are no more subscribers.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new IntersectionObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n }, {\n threshold: 0\n })\n))\n .pipe(\n switchMap(observer => merge(NEVER, of(observer))\n .pipe(\n finalize(() => observer.disconnect())\n )\n ),\n shareReplay(1)\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch element visibility\n *\n * @param el - Element\n *\n * @returns Element visibility observable\n */\nexport function watchElementVisibility(\n el: HTMLElement\n): Observable {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(({ isIntersecting }) => isIntersecting)\n )\n )\n )\n}\n\n/**\n * Watch element boundary\n *\n * This function returns an observable which emits whether the bottom content\n * boundary (= scroll offset) of an element is within a certain threshold.\n *\n * @param el - Element\n * @param threshold - Threshold\n *\n * @returns Element boundary observable\n */\nexport function watchElementBoundary(\n el: HTMLElement, threshold = 16\n): Observable {\n return watchElementContentOffset(el)\n .pipe(\n map(({ y }) => {\n const visible = getElementSize(el)\n const content = getElementContentSize(el)\n return y >= (\n content.height - visible.height - threshold\n )\n }),\n distinctUntilChanged()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getElement } from \"../element\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle\n */\nexport type Toggle =\n | \"drawer\" /* Toggle for drawer */\n | \"search\" /* Toggle for search */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle map\n */\nconst toggles: Record = {\n drawer: getElement(\"[data-md-toggle=drawer]\"),\n search: getElement(\"[data-md-toggle=search]\")\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the value of a toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value\n */\nexport function getToggle(name: Toggle): boolean {\n return toggles[name].checked\n}\n\n/**\n * Set toggle\n *\n * Simulating a click event seems to be the most cross-browser compatible way\n * of changing the value while also emitting a `change` event. Before, Material\n * used `CustomEvent` to programmatically change the value of a toggle, but this\n * is a much simpler and cleaner solution which doesn't require a polyfill.\n *\n * @param name - Toggle\n * @param value - Toggle value\n */\nexport function setToggle(name: Toggle, value: boolean): void {\n if (toggles[name].checked !== value)\n toggles[name].click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch toggle\n *\n * @param name - Toggle\n *\n * @returns Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable {\n const el = toggles[name]\n return fromEvent(el, \"change\")\n .pipe(\n map(() => el.checked),\n startWith(el.checked)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n share\n} from \"rxjs\"\n\nimport { getActiveElement } from \"../element\"\nimport { getToggle } from \"../toggle\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Keyboard mode\n */\nexport type KeyboardMode =\n | \"global\" /* Global */\n | \"search\" /* Search is open */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Keyboard\n */\nexport interface Keyboard {\n mode: KeyboardMode /* Keyboard mode */\n type: string /* Key type */\n claim(): void /* Key claim */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether an element may receive keyboard input\n *\n * @param el - Element\n * @param type - Key type\n *\n * @returns Test result\n */\nfunction isSusceptibleToKeyboard(\n el: HTMLElement, type: string\n): boolean {\n switch (el.constructor) {\n\n /* Input elements */\n case HTMLInputElement:\n /* @ts-expect-error - omit unnecessary type cast */\n if (el.type === \"radio\")\n return /^Arrow/.test(type)\n else\n return true\n\n /* Select element and textarea */\n case HTMLSelectElement:\n case HTMLTextAreaElement:\n return true\n\n /* Everything else */\n default:\n return el.isContentEditable\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch keyboard\n *\n * @returns Keyboard observable\n */\nexport function watchKeyboard(): Observable {\n return fromEvent(window, \"keydown\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n map(ev => ({\n mode: getToggle(\"search\") ? \"search\" : \"global\",\n type: ev.key,\n claim() {\n ev.preventDefault()\n ev.stopPropagation()\n }\n } as Keyboard)),\n filter(({ mode, type }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active, type)\n }\n return true\n }),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function returns a `URL` object (and not `Location`) to normalize the\n * typings across the application. Furthermore, locations need to be tracked\n * without setting them and `Location` is a singleton which represents the\n * current location.\n *\n * @returns URL\n */\nexport function getLocation(): URL {\n return new URL(location.href)\n}\n\n/**\n * Set location\n *\n * @param url - URL to change to\n */\nexport function setLocation(url: URL): void {\n location.href = url.href\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @returns Location subject\n */\nexport function watchLocation(): Subject {\n return new Subject()\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { JSX as JSXInternal } from \"preact\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * HTML attributes\n */\ntype Attributes =\n & JSXInternal.HTMLAttributes\n & JSXInternal.SVGAttributes\n & Record\n\n/**\n * Child element\n */\ntype Child =\n | HTMLElement\n | Text\n | string\n | number\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Append a child node to an element\n *\n * @param el - Element\n * @param child - Child node(s)\n */\nfunction appendChild(el: HTMLElement, child: Child | Child[]): void {\n\n /* Handle primitive types (including raw HTML) */\n if (typeof child === \"string\" || typeof child === \"number\") {\n el.innerHTML += child.toString()\n\n /* Handle nodes */\n } else if (child instanceof Node) {\n el.appendChild(child)\n\n /* Handle nested children */\n } else if (Array.isArray(child)) {\n for (const node of child)\n appendChild(el, node)\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * JSX factory\n *\n * @template T - Element type\n *\n * @param tag - HTML tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @returns Element\n */\nexport function h(\n tag: T, attributes?: Attributes | null, ...children: Child[]\n): HTMLElementTagNameMap[T]\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T\n\nexport function h(\n tag: string, attributes?: Attributes | null, ...children: Child[]\n): T {\n const el = document.createElement(tag)\n\n /* Set attributes, if any */\n if (attributes)\n for (const attr of Object.keys(attributes)) {\n if (typeof attributes[attr] === \"undefined\")\n continue\n\n /* Set default attribute or boolean */\n if (typeof attributes[attr] !== \"boolean\")\n el.setAttribute(attr, attributes[attr])\n else\n el.setAttribute(attr, \"\")\n }\n\n /* Append child nodes */\n for (const child of children)\n appendChild(el, child)\n\n /* Return element */\n return el as T\n}\n\n/* ----------------------------------------------------------------------------\n * Namespace\n * ------------------------------------------------------------------------- */\n\nexport declare namespace h {\n namespace JSX {\n type Element = HTMLElement\n type IntrinsicElements = JSXInternal.IntrinsicElements\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Truncate a string after the given number of characters\n *\n * This is not a very reasonable approach, since the summaries kind of suck.\n * It would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it, but this note was\n * written three years ago, so who knows if we'll ever fix it.\n *\n * @param value - Value to be truncated\n * @param n - Number of characters\n *\n * @returns Truncated value\n */\nexport function truncate(value: string, n: number): string {\n let i = n\n if (value.length > i) {\n while (value[i] !== \" \" && --i > 0) { /* keep eating */ }\n return `${value.substring(0, i)}...`\n }\n return value\n}\n\n/**\n * Round a number for display with repository facts\n *\n * This is a reverse-engineered version of GitHub's weird rounding algorithm\n * for stars, forks and all other numbers. While all numbers below `1,000` are\n * returned as-is, bigger numbers are converted to fixed numbers:\n *\n * - `1,049` => `1k`\n * - `1,050` => `1.1k`\n * - `1,949` => `1.9k`\n * - `1,950` => `2k`\n *\n * @param value - Original value\n *\n * @returns Rounded value\n */\nexport function round(value: number): string {\n if (value > 999) {\n const digits = +((value - 950) % 1000 > 99)\n return `${((value + 0.000001) / 1000).toFixed(digits)}k`\n } else {\n return value.toString()\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n shareReplay,\n startWith\n} from \"rxjs\"\n\nimport { getOptionalElement } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location hash\n *\n * @returns Location hash\n */\nexport function getLocationHash(): string {\n return location.hash.substring(1)\n}\n\n/**\n * Set location hash\n *\n * Setting a new fragment identifier via `location.hash` will have no effect\n * if the value doesn't change. When a new fragment identifier is set, we want\n * the browser to target the respective element at all times, which is why we\n * use this dirty little trick.\n *\n * @param hash - Location hash\n */\nexport function setLocationHash(hash: string): void {\n const el = h(\"a\", { href: hash })\n el.addEventListener(\"click\", ev => ev.stopPropagation())\n el.click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location hash\n *\n * @returns Location hash observable\n */\nexport function watchLocationHash(): Observable {\n return fromEvent(window, \"hashchange\")\n .pipe(\n map(getLocationHash),\n startWith(getLocationHash()),\n filter(hash => hash.length > 0),\n shareReplay(1)\n )\n}\n\n/**\n * Watch location target\n *\n * @returns Location target observable\n */\nexport function watchLocationTarget(): Observable {\n return watchLocationHash()\n .pipe(\n map(id => getOptionalElement(`[id=\"${id}\"]`)!),\n filter(el => typeof el !== \"undefined\")\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n fromEvent,\n fromEventPattern,\n map,\n merge,\n startWith,\n switchMap\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\n *\n * Note that although `MediaQueryList.addListener` is deprecated we have to\n * use it, because it's the only way to ensure proper downward compatibility.\n *\n * @see https://bit.ly/3dUBH2m - GitHub issue\n *\n * @param query - Media query\n *\n * @returns Media observable\n */\nexport function watchMedia(query: string): Observable {\n const media = matchMedia(query)\n return fromEventPattern(next => (\n media.addListener(() => next(media.matches))\n ))\n .pipe(\n startWith(media.matches)\n )\n}\n\n/**\n * Watch print mode\n *\n * @returns Print observable\n */\nexport function watchPrint(): Observable {\n const media = matchMedia(\"print\")\n return merge(\n fromEvent(window, \"beforeprint\").pipe(map(() => true)),\n fromEvent(window, \"afterprint\").pipe(map(() => false))\n )\n .pipe(\n startWith(media.matches)\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Toggle an observable with a media observable\n *\n * @template T - Data type\n *\n * @param query$ - Media observable\n * @param factory - Observable factory\n *\n * @returns Toggled observable\n */\nexport function at(\n query$: Observable, factory: () => Observable\n): Observable {\n return query$\n .pipe(\n switchMap(active => active ? factory() : EMPTY)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n from,\n map,\n of,\n shareReplay,\n switchMap,\n throwError\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the given URL\n *\n * If the request fails (e.g. when dispatched from `file://` locations), the\n * observable will complete without emitting a value.\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Response observable\n */\nexport function request(\n url: URL | string, options: RequestInit = { credentials: \"same-origin\" }\n): Observable {\n return from(fetch(`${url}`, options))\n .pipe(\n catchError(() => EMPTY),\n switchMap(res => res.status !== 200\n ? throwError(() => new Error(res.statusText))\n : of(res)\n )\n )\n}\n\n/**\n * Fetch JSON from the given URL\n *\n * @template T - Data type\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestJSON(\n url: URL | string, options?: RequestInit\n): Observable {\n return request(url, options)\n .pipe(\n switchMap(res => res.json()),\n shareReplay(1)\n )\n}\n\n/**\n * Fetch XML from the given URL\n *\n * @param url - Request URL\n * @param options - Options\n *\n * @returns Data observable\n */\nexport function requestXML(\n url: URL | string, options?: RequestInit\n): Observable {\n const dom = new DOMParser()\n return request(url, options)\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/xml\")),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n switchMap,\n take,\n throwError\n} from \"rxjs\"\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create and load a `script` element\n *\n * This function returns an observable that will emit when the script was\n * successfully loaded, or throw an error if it didn't.\n *\n * @param src - Script URL\n *\n * @returns Script observable\n */\nexport function watchScript(src: string): Observable {\n const script = h(\"script\", { src })\n return defer(() => {\n document.head.appendChild(script)\n return merge(\n fromEvent(script, \"load\"),\n fromEvent(script, \"error\")\n .pipe(\n switchMap(() => (\n throwError(() => new ReferenceError(`Invalid script: ${src}`))\n ))\n )\n )\n .pipe(\n map(() => undefined),\n finalize(() => document.head.removeChild(script)),\n take(1)\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n merge,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport offset\n */\nexport interface ViewportOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport offset\n *\n * On iOS Safari, viewport offset can be negative due to overflow scrolling.\n * As this may induce strange behaviors downstream, we'll just limit it to 0.\n *\n * @returns Viewport offset\n */\nexport function getViewportOffset(): ViewportOffset {\n return {\n x: Math.max(0, scrollX),\n y: Math.max(0, scrollY)\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport offset\n *\n * @returns Viewport offset observable\n */\nexport function watchViewportOffset(): Observable {\n return merge(\n fromEvent(window, \"scroll\", { passive: true }),\n fromEvent(window, \"resize\", { passive: true })\n )\n .pipe(\n map(getViewportOffset),\n startWith(getViewportOffset())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n startWith\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport size\n */\nexport interface ViewportSize {\n width: number /* Viewport width */\n height: number /* Viewport height */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport size\n *\n * @returns Viewport size\n */\nexport function getViewportSize(): ViewportSize {\n return {\n width: innerWidth,\n height: innerHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport size\n *\n * @returns Viewport size observable\n */\nexport function watchViewportSize(): Observable {\n return fromEvent(window, \"resize\", { passive: true })\n .pipe(\n map(getViewportSize),\n startWith(getViewportSize())\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n map,\n shareReplay\n} from \"rxjs\"\n\nimport {\n ViewportOffset,\n watchViewportOffset\n} from \"../offset\"\nimport {\n ViewportSize,\n watchViewportSize\n} from \"../size\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport\n */\nexport interface Viewport {\n offset: ViewportOffset /* Viewport offset */\n size: ViewportSize /* Viewport size */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport\n *\n * @returns Viewport observable\n */\nexport function watchViewport(): Observable {\n return combineLatest([\n watchViewportOffset(),\n watchViewportSize()\n ])\n .pipe(\n map(([offset, size]) => ({ offset, size })),\n shareReplay(1)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilKeyChanged,\n map\n} from \"rxjs\"\n\nimport { Header } from \"~/components\"\n\nimport { getElementOffset } from \"../../element\"\nimport { Viewport } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
/* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport relative to element\n *\n * @param el - Element\n * @param options - Options\n *\n * @returns Viewport observable\n */\nexport function watchViewportAt(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const size$ = viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\")\n )\n\n /* Compute element offset */\n const offset$ = combineLatest([size$, header$])\n .pipe(\n map(() => getElementOffset(el))\n )\n\n /* Compute relative viewport, return hot observable */\n return combineLatest([header$, viewport$, offset$])\n .pipe(\n map(([{ height }, { offset, size }, { x, y }]) => ({\n offset: {\n x: offset.x - x,\n y: offset.y - y + height\n },\n size\n }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n fromEvent,\n map,\n share,\n switchMap,\n tap,\n throttle\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Worker message\n */\nexport interface WorkerMessage {\n type: unknown /* Message type */\n data?: unknown /* Message data */\n}\n\n/**\n * Worker handler\n *\n * @template T - Message type\n */\nexport interface WorkerHandler<\n T extends WorkerMessage\n> {\n tx$: Subject /* Message transmission subject */\n rx$: Observable /* Message receive observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n *\n * @template T - Worker message type\n */\ninterface WatchOptions {\n tx$: Observable /* Message transmission observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch a web worker\n *\n * This function returns an observable that sends all values emitted by the\n * message observable to the web worker. Web worker communication is expected\n * to be bidirectional (request-response) and synchronous. Messages that are\n * emitted during a pending request are throttled, the last one is emitted.\n *\n * @param worker - Web worker\n * @param options - Options\n *\n * @returns Worker message observable\n */\nexport function watchWorker(\n worker: Worker, { tx$ }: WatchOptions\n): Observable {\n\n /* Intercept messages from worker-like objects */\n const rx$ = fromEvent(worker, \"message\")\n .pipe(\n map(({ data }) => data as T)\n )\n\n /* Send and receive messages, return hot observable */\n return tx$\n .pipe(\n throttle(() => rx$, { leading: true, trailing: true }),\n tap(message => worker.postMessage(message)),\n switchMap(() => rx$),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getLocation } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flag\n */\nexport type Flag =\n | \"announce.dismiss\" /* Dismissable announcement bar */\n | \"content.code.annotate\" /* Code annotations */\n | \"content.lazy\" /* Lazy content elements */\n | \"content.tabs.link\" /* Link content tabs */\n | \"header.autohide\" /* Hide header */\n | \"navigation.expand\" /* Automatic expansion */\n | \"navigation.indexes\" /* Section pages */\n | \"navigation.instant\" /* Instant loading */\n | \"navigation.sections\" /* Section navigation */\n | \"navigation.tabs\" /* Tabs navigation */\n | \"navigation.tabs.sticky\" /* Tabs navigation (sticky) */\n | \"navigation.top\" /* Back-to-top button */\n | \"navigation.tracking\" /* Anchor tracking */\n | \"search.highlight\" /* Search highlighting */\n | \"search.share\" /* Search sharing */\n | \"search.suggest\" /* Search suggestions */\n | \"toc.follow\" /* Following table of contents */\n | \"toc.integrate\" /* Integrated table of contents */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Translation\n */\nexport type Translation =\n | \"clipboard.copy\" /* Copy to clipboard */\n | \"clipboard.copied\" /* Copied to clipboard */\n | \"search.config.lang\" /* Search language */\n | \"search.config.pipeline\" /* Search pipeline */\n | \"search.config.separator\" /* Search separator */\n | \"search.placeholder\" /* Search */\n | \"search.result.placeholder\" /* Type to start searching */\n | \"search.result.none\" /* No matching documents */\n | \"search.result.one\" /* 1 matching document */\n | \"search.result.other\" /* # matching documents */\n | \"search.result.more.one\" /* 1 more on this page */\n | \"search.result.more.other\" /* # more on this page */\n | \"search.result.term.missing\" /* Missing */\n | \"select.version.title\" /* Version selector */\n\n/**\n * Translations\n */\nexport type Translations = Record\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Versioning\n */\nexport interface Versioning {\n provider: \"mike\" /* Version provider */\n default?: string /* Default version */\n}\n\n/**\n * Configuration\n */\nexport interface Config {\n base: string /* Base URL */\n features: Flag[] /* Feature flags */\n translations: Translations /* Translations */\n search: string /* Search worker URL */\n tags?: Record /* Tags mapping */\n version?: Versioning /* Versioning */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration and make base URL absolute\n */\nconst script = getElement(\"#__config\")\nconst config: Config = JSON.parse(script.textContent!)\nconfig.base = `${new URL(config.base, getLocation())}`\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve global configuration\n *\n * @returns Global configuration\n */\nexport function configuration(): Config {\n return config\n}\n\n/**\n * Check whether a feature flag is enabled\n *\n * @param flag - Feature flag\n *\n * @returns Test result\n */\nexport function feature(flag: Flag): boolean {\n return config.features.includes(flag)\n}\n\n/**\n * Retrieve the translation for the given key\n *\n * @param key - Key to be translated\n * @param value - Positional value, if any\n *\n * @returns Translation\n */\nexport function translation(\n key: Translation, value?: string | number\n): string {\n return typeof value !== \"undefined\"\n ? config.translations[key].replace(\"#\", value.toString())\n : config.translations[key]\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElement, getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type\n */\nexport type ComponentType =\n | \"announce\" /* Announcement bar */\n | \"container\" /* Container */\n | \"consent\" /* Consent */\n | \"content\" /* Content */\n | \"dialog\" /* Dialog */\n | \"header\" /* Header */\n | \"header-title\" /* Header title */\n | \"header-topic\" /* Header topic */\n | \"main\" /* Main area */\n | \"outdated\" /* Version warning */\n | \"palette\" /* Color palette */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-result\" /* Search results */\n | \"search-share\" /* Search sharing */\n | \"search-suggest\" /* Search suggestions */\n | \"sidebar\" /* Sidebar */\n | \"skip\" /* Skip link */\n | \"source\" /* Repository information */\n | \"tabs\" /* Navigation tabs */\n | \"toc\" /* Table of contents */\n | \"top\" /* Back-to-top button */\n\n/**\n * Component\n *\n * @template T - Component type\n * @template U - Reference type\n */\nexport type Component<\n T extends {} = {},\n U extends HTMLElement = HTMLElement\n> =\n T & {\n ref: U /* Component reference */\n }\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component type map\n */\ninterface ComponentTypeMap {\n \"announce\": HTMLElement /* Announcement bar */\n \"container\": HTMLElement /* Container */\n \"consent\": HTMLElement /* Consent */\n \"content\": HTMLElement /* Content */\n \"dialog\": HTMLElement /* Dialog */\n \"header\": HTMLElement /* Header */\n \"header-title\": HTMLElement /* Header title */\n \"header-topic\": HTMLElement /* Header topic */\n \"main\": HTMLElement /* Main area */\n \"outdated\": HTMLElement /* Version warning */\n \"palette\": HTMLElement /* Color palette */\n \"search\": HTMLElement /* Search */\n \"search-query\": HTMLInputElement /* Search input */\n \"search-result\": HTMLElement /* Search results */\n \"search-share\": HTMLAnchorElement /* Search sharing */\n \"search-suggest\": HTMLElement /* Search suggestions */\n \"sidebar\": HTMLElement /* Sidebar */\n \"skip\": HTMLAnchorElement /* Skip link */\n \"source\": HTMLAnchorElement /* Repository information */\n \"tabs\": HTMLElement /* Navigation tabs */\n \"toc\": HTMLElement /* Table of contents */\n \"top\": HTMLAnchorElement /* Back-to-top button */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the element for a given component or throw a reference error\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Element\n */\nexport function getComponentElement(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T] {\n return getElement(`[data-md-component=${type}]`, node)\n}\n\n/**\n * Retrieve all elements for a given component\n *\n * @template T - Component type\n *\n * @param type - Component type\n * @param node - Node of reference\n *\n * @returns Elements\n */\nexport function getComponentElements(\n type: T, node: ParentNode = document\n): ComponentTypeMap[T][] {\n return getElements(`[data-md-component=${type}]`, node)\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n finalize,\n fromEvent,\n map,\n startWith,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport { getElement } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Announcement bar\n */\nexport interface Announce {\n hash: number /* Content hash */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch announcement bar\n *\n * @param el - Announcement bar element\n *\n * @returns Announcement bar observable\n */\nexport function watchAnnounce(\n el: HTMLElement\n): Observable {\n const button = getElement(\".md-typeset > :first-child\", el)\n return fromEvent(button, \"click\", { once: true })\n .pipe(\n map(() => getElement(\".md-typeset\", el)),\n map(content => ({ hash: __md_hash(content.innerHTML) }))\n )\n}\n\n/**\n * Mount announcement bar\n *\n * @param el - Announcement bar element\n *\n * @returns Announcement bar component observable\n */\nexport function mountAnnounce(\n el: HTMLElement\n): Observable> {\n if (!feature(\"announce.dismiss\") || !el.childElementCount)\n return EMPTY\n\n /* Mount component on subscription */\n return defer(() => {\n const push$ = new Subject()\n push$\n .pipe(\n startWith({ hash: __md_get(\"__announce\") })\n )\n .subscribe(({ hash }) => {\n if (hash && hash === (__md_get(\"__announce\") ?? hash)) {\n el.hidden = true\n\n /* Persist preference in local storage */\n __md_set(\"__announce\", hash)\n }\n })\n\n /* Create and return component */\n return watchAnnounce(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n finalize,\n map,\n tap\n} from \"rxjs\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Consent\n */\nexport interface Consent {\n hidden: boolean /* Consent is hidden */\n}\n\n/**\n * Consent defaults\n */\nexport interface ConsentDefaults {\n analytics?: boolean /* Consent for Analytics */\n github?: boolean /* Consent for GitHub */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Target observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch consent\n *\n * @param el - Consent element\n * @param options - Options\n *\n * @returns Consent observable\n */\nexport function watchConsent(\n el: HTMLElement, { target$ }: WatchOptions\n): Observable {\n return target$\n .pipe(\n map(target => ({ hidden: target !== el }))\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount consent\n *\n * @param el - Consent element\n * @param options - Options\n *\n * @returns Consent component observable\n */\nexport function mountConsent(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const internal$ = new Subject()\n internal$.subscribe(({ hidden }) => {\n el.hidden = hidden\n })\n\n /* Create and return component */\n return watchConsent(el, options)\n .pipe(\n tap(state => internal$.next(state)),\n finalize(() => internal$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n map,\n mergeWith,\n switchMap,\n take,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n getElementContentSize,\n watchElementSize,\n watchElementVisibility\n} from \"~/browser\"\nimport { renderClipboardButton } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotationList\n} from \"../../annotation\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Code block\n */\nexport interface CodeBlock {\n scrollable: boolean /* Code block overflows */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Global sequence number for code blocks\n */\nlet sequence = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find candidate list element directly following a code block\n *\n * @param el - Code block element\n *\n * @returns List element or nothing\n */\nfunction findCandidateList(el: HTMLElement): HTMLElement | undefined {\n if (el.nextElementSibling) {\n const sibling = el.nextElementSibling as HTMLElement\n if (sibling.tagName === \"OL\")\n return sibling\n\n /* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */\n else if (sibling.tagName === \"P\" && !sibling.children.length)\n return findCandidateList(sibling)\n }\n\n /* Everything else */\n return undefined\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch code block\n *\n * This function monitors size changes of the viewport, as well as switches of\n * content tabs with embedded code blocks, as both may trigger overflow.\n *\n * @param el - Code block element\n *\n * @returns Code block observable\n */\nexport function watchCodeBlock(\n el: HTMLElement\n): Observable {\n return watchElementSize(el)\n .pipe(\n map(({ width }) => {\n const content = getElementContentSize(el)\n return {\n scrollable: content.width > width\n }\n }),\n distinctUntilKeyChanged(\"scrollable\")\n )\n}\n\n/**\n * Mount code block\n *\n * This function ensures that an overflowing code block is focusable through\n * keyboard, so it can be scrolled without a mouse to improve on accessibility.\n * Furthermore, if code annotations are enabled, they are mounted if and only\n * if the code block is currently visible, e.g., not in a hidden content tab.\n *\n * Note that code blocks may be mounted eagerly or lazily. If they're mounted\n * lazily (on first visibility), code annotation anchor links will not work,\n * as they are evaluated on initial page load, and code annotations in general\n * might feel a little bumpier.\n *\n * @param el - Code block element\n * @param options - Options\n *\n * @returns Code block and annotation component observable\n */\nexport function mountCodeBlock(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const { matches: hover } = matchMedia(\"(hover)\")\n\n /* Defer mounting of code block - see https://bit.ly/3vHVoVD */\n const factory$ = defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ scrollable }) => {\n if (scrollable && hover)\n el.setAttribute(\"tabindex\", \"0\")\n else\n el.removeAttribute(\"tabindex\")\n })\n\n /* Render button for Clipboard.js integration */\n if (ClipboardJS.isSupported()) {\n const parent = el.closest(\"pre\")!\n parent.id = `__code_${++sequence}`\n parent.insertBefore(\n renderClipboardButton(parent.id),\n el\n )\n }\n\n /* Handle code annotations */\n const container = el.closest(\".highlight\")\n if (container instanceof HTMLElement) {\n const list = findCandidateList(container)\n\n /* Mount code annotations, if enabled */\n if (typeof list !== \"undefined\" && (\n container.classList.contains(\"annotate\") ||\n feature(\"content.code.annotate\")\n )) {\n const annotations$ = mountAnnotationList(list, el, options)\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state })),\n mergeWith(\n watchElementSize(container)\n .pipe(\n map(({ width, height }) => width && height),\n distinctUntilChanged(),\n switchMap(active => active ? annotations$ : EMPTY)\n )\n )\n )\n }\n }\n\n /* Create and return component */\n return watchCodeBlock(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n\n /* Mount code block lazily */\n if (feature(\"content.lazy\"))\n return watchElementVisibility(el)\n .pipe(\n filter(visible => visible),\n take(1),\n switchMap(() => factory$)\n )\n\n /* Mount code block */\n return factory$\n}\n", "/*\n * Copyright (c) 2016-2021 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a tooltip\n *\n * @param id - Tooltip identifier\n *\n * @returns Element\n */\nexport function renderTooltip(id?: string): HTMLElement {\n return (\n
\n
\n
\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\nimport { renderTooltip } from \"../tooltip\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render an annotation\n *\n * @param id - Annotation identifier\n * @param prefix - Tooltip identifier prefix\n *\n * @returns Element\n */\nexport function renderAnnotation(\n id: string | number, prefix?: string\n): HTMLElement {\n prefix = prefix ? `${prefix}_annotation_${id}` : undefined\n\n /* Render tooltip with anchor, if given */\n if (prefix) {\n const anchor = prefix ? `#${prefix}` : undefined\n return (\n \n )\n } else {\n return (\n \n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a 'copy-to-clipboard' button\n *\n * @param id - Unique identifier\n *\n * @returns Element\n */\nexport function renderClipboardButton(id: string): HTMLElement {\n return (\n code`}\n >\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ComponentChild } from \"preact\"\n\nimport { configuration, feature, translation } from \"~/_\"\nimport {\n SearchDocument,\n SearchMetadata,\n SearchResultItem\n} from \"~/integrations/search\"\nimport { h, truncate } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Render flag\n */\nconst enum Flag {\n TEASER = 1, /* Render teaser */\n PARENT = 2 /* Render as parent */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper function\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search document\n *\n * @param document - Search document\n * @param flag - Render flags\n *\n * @returns Element\n */\nfunction renderSearchDocument(\n document: SearchDocument & SearchMetadata, flag: Flag\n): HTMLElement {\n const parent = flag & Flag.PARENT\n const teaser = flag & Flag.TEASER\n\n /* Render missing query terms */\n const missing = Object.keys(document.terms)\n .filter(key => !document.terms[key])\n .reduce((list, key) => [\n ...list, {key}, \" \"\n ], [])\n .slice(0, -1)\n\n /* Assemble query string for highlighting */\n const url = new URL(document.location)\n if (feature(\"search.highlight\"))\n url.searchParams.set(\"h\", Object.entries(document.terms)\n .filter(([, match]) => match)\n .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), \"\")\n )\n\n /* Render article or section, depending on flags */\n const { tags } = configuration()\n return (\n \n \n {parent > 0 &&
}\n

{document.title}

\n {teaser > 0 && document.text.length > 0 &&\n

\n {truncate(document.text, 320)}\n

\n }\n {document.tags && (\n
\n {document.tags.map(tag => {\n const id = tag.replace(/<[^>]+>/g, \"\")\n const type = tags\n ? id in tags\n ? `md-tag-icon md-tag-icon--${tags[id]}`\n : \"md-tag-icon\"\n : \"\"\n return (\n {tag}\n )\n })}\n
\n )}\n {teaser > 0 && missing.length > 0 &&\n

\n {translation(\"search.result.term.missing\")}: {...missing}\n

\n }\n \n
\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n *\n * @returns Element\n */\nexport function renderSearchResultItem(\n result: SearchResultItem\n): HTMLElement {\n const threshold = result[0].score\n const docs = [...result]\n\n /* Find and extract parent article */\n const parent = docs.findIndex(doc => !doc.location.includes(\"#\"))\n const [article] = docs.splice(parent, 1)\n\n /* Determine last index above threshold */\n let index = docs.findIndex(doc => doc.score < threshold)\n if (index === -1)\n index = docs.length\n\n /* Partition sections */\n const best = docs.slice(0, index)\n const more = docs.slice(index)\n\n /* Render children */\n const children = [\n renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)),\n ...best.map(section => renderSearchDocument(section, Flag.TEASER)),\n ...more.length ? [\n
\n \n {more.length > 0 && more.length === 1\n ? translation(\"search.result.more.one\")\n : translation(\"search.result.more.other\", more.length)\n }\n \n {...more.map(section => renderSearchDocument(section, Flag.TEASER))}\n
\n ] : []\n ]\n\n /* Render search result */\n return (\n
  • \n {children}\n
  • \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SourceFacts } from \"~/components\"\nimport { h, round } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render repository facts\n *\n * @param facts - Repository facts\n *\n * @returns Element\n */\nexport function renderSourceFacts(facts: SourceFacts): HTMLElement {\n return (\n
      \n {Object.entries(facts).map(([key, value]) => (\n
    • \n {typeof value === \"number\" ? round(value) : value}\n
    • \n ))}\n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Tabbed control type\n */\ntype TabbedControlType =\n | \"prev\"\n | \"next\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render control for content tabs\n *\n * @param type - Control type\n *\n * @returns Element\n */\nexport function renderTabbedControl(\n type: TabbedControlType\n): HTMLElement {\n const classes = `tabbed-control tabbed-control--${type}`\n return (\n \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a table inside a wrapper to improve scrolling on mobile\n *\n * @param table - Table element\n *\n * @returns Element\n */\nexport function renderTable(table: HTMLElement): HTMLElement {\n return (\n
    \n
    \n {table}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { configuration, translation } from \"~/_\"\nimport { h } from \"~/utilities\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Version\n */\nexport interface Version {\n version: string /* Version identifier */\n title: string /* Version title */\n aliases: string[] /* Version aliases */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version\n *\n * @param version - Version\n *\n * @returns Element\n */\nfunction renderVersion(version: Version): HTMLElement {\n const config = configuration()\n\n /* Ensure trailing slash - see https://bit.ly/3rL5u3f */\n const url = new URL(`../${version.version}/`, config.base)\n return (\n
  • \n \n {version.title}\n \n
  • \n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a version selector\n *\n * @param versions - Versions\n * @param active - Active version\n *\n * @returns Element\n */\nexport function renderVersionSelector(\n versions: Version[], active: Version\n): HTMLElement {\n return (\n
    \n \n {active.title}\n \n
      \n {versions.map(renderVersion)}\n
    \n
    \n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n auditTime,\n combineLatest,\n debounceTime,\n defer,\n delay,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n switchMap,\n take,\n takeLast,\n takeUntil,\n tap,\n throttleTime,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n ElementOffset,\n getActiveElement,\n getElementSize,\n watchElementContentOffset,\n watchElementFocus,\n watchElementOffset,\n watchElementVisibility\n} from \"~/browser\"\n\nimport { Component } from \"../../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Annotation\n */\nexport interface Annotation {\n active: boolean /* Annotation is active */\n offset: ElementOffset /* Annotation offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n *\n * @returns Annotation observable\n */\nexport function watchAnnotation(\n el: HTMLElement, container: HTMLElement\n): Observable {\n const offset$ = defer(() => combineLatest([\n watchElementOffset(el),\n watchElementContentOffset(container)\n ]))\n .pipe(\n map(([{ x, y }, scroll]): ElementOffset => {\n const { width, height } = getElementSize(el)\n return ({\n x: x - scroll.x + width / 2,\n y: y - scroll.y + height / 2\n })\n })\n )\n\n /* Actively watch annotation on focus */\n return watchElementFocus(el)\n .pipe(\n switchMap(active => offset$\n .pipe(\n map(offset => ({ active, offset })),\n take(+!active || Infinity)\n )\n )\n )\n}\n\n/**\n * Mount annotation\n *\n * @param el - Annotation element\n * @param container - Containing element\n * @param options - Options\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotation(\n el: HTMLElement, container: HTMLElement, { target$ }: MountOptions\n): Observable> {\n const [tooltip, index] = Array.from(el.children)\n\n /* Mount component on subscription */\n return defer(() => {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n push$.subscribe({\n\n /* Handle emission */\n next({ offset }) {\n el.style.setProperty(\"--md-tooltip-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-tooltip-y\", `${offset.y}px`)\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-x\")\n el.style.removeProperty(\"--md-tooltip-y\")\n }\n })\n\n /* Start animation only when annotation is visible */\n watchElementVisibility(el)\n .pipe(\n takeUntil(done$)\n )\n .subscribe(visible => {\n el.toggleAttribute(\"data-md-visible\", visible)\n })\n\n /* Toggle tooltip presence to mitigate empty lines when copying */\n merge(\n push$.pipe(filter(({ active }) => active)),\n push$.pipe(debounceTime(250), filter(({ active }) => !active))\n )\n .subscribe({\n\n /* Handle emission */\n next({ active }) {\n if (active)\n el.prepend(tooltip)\n else\n tooltip.remove()\n },\n\n /* Handle complete */\n complete() {\n el.prepend(tooltip)\n }\n })\n\n /* Toggle tooltip visibility */\n push$\n .pipe(\n auditTime(16, animationFrameScheduler)\n )\n .subscribe(({ active }) => {\n tooltip.classList.toggle(\"md-tooltip--active\", active)\n })\n\n /* Track relative origin of tooltip */\n push$\n .pipe(\n throttleTime(125, animationFrameScheduler),\n filter(() => !!el.offsetParent),\n map(() => el.offsetParent!.getBoundingClientRect()),\n map(({ x }) => x)\n )\n .subscribe({\n\n /* Handle emission */\n next(origin) {\n if (origin)\n el.style.setProperty(\"--md-tooltip-0\", `${-origin}px`)\n else\n el.style.removeProperty(\"--md-tooltip-0\")\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-tooltip-0\")\n }\n })\n\n /* Allow to copy link without scrolling to anchor */\n fromEvent(index, \"click\")\n .pipe(\n takeUntil(done$),\n filter(ev => !(ev.metaKey || ev.ctrlKey))\n )\n .subscribe(ev => ev.preventDefault())\n\n /* Allow to open link in new tab or blur on close */\n fromEvent(index, \"mousedown\")\n .pipe(\n takeUntil(done$),\n withLatestFrom(push$)\n )\n .subscribe(([ev, { active }]) => {\n\n /* Open in new tab */\n if (ev.button !== 0 || ev.metaKey || ev.ctrlKey) {\n ev.preventDefault()\n\n /* Close annotation */\n } else if (active) {\n ev.preventDefault()\n\n /* Focus parent annotation, if any */\n const parent = el.parentElement!.closest(\".md-annotation\")\n if (parent instanceof HTMLElement)\n parent.focus()\n else\n getActiveElement()?.blur()\n }\n })\n\n /* Open and focus annotation on location target */\n target$\n .pipe(\n takeUntil(done$),\n filter(target => target === tooltip),\n delay(125)\n )\n .subscribe(() => el.focus())\n\n /* Create and return component */\n return watchAnnotation(el, container)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n finalize,\n merge,\n share,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport {\n getElement,\n getElements,\n getOptionalElement\n} from \"~/browser\"\nimport { renderAnnotation } from \"~/templates\"\n\nimport { Component } from \"../../../_\"\nimport {\n Annotation,\n mountAnnotation\n} from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Find all annotation markers in the given code block\n *\n * @param container - Containing element\n *\n * @returns Annotation markers\n */\nfunction findAnnotationMarkers(container: HTMLElement): Text[] {\n const markers: Text[] = []\n for (const el of getElements(\".c, .c1, .cm\", container)) {\n const nodes: Text[] = []\n\n /* Find all text nodes in current element */\n const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT)\n for (let node = it.nextNode(); node; node = it.nextNode())\n nodes.push(node as Text)\n\n /* Find all markers in each text node */\n for (let text of nodes) {\n let match: RegExpExecArray | null\n\n /* Split text at marker and add to list */\n while ((match = /(\\(\\d+\\))(!)?/.exec(text.textContent!))) {\n const [, id, force] = match\n if (typeof force === \"undefined\") {\n const marker = text.splitText(match.index)\n text = marker.splitText(id.length)\n markers.push(marker)\n\n /* Replace entire text with marker */\n } else {\n text.textContent = id\n markers.push(text)\n break\n }\n }\n }\n }\n return markers\n}\n\n/**\n * Swap the child nodes of two elements\n *\n * @param source - Source element\n * @param target - Target element\n */\nfunction swap(source: HTMLElement, target: HTMLElement): void {\n target.append(...Array.from(source.childNodes))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount annotation list\n *\n * This function analyzes the containing code block and checks for markers\n * referring to elements in the given annotation list. If no markers are found,\n * the list is left untouched. Otherwise, list elements are rendered as\n * annotations inside the code block.\n *\n * @param el - Annotation list element\n * @param container - Containing element\n * @param options - Options\n *\n * @returns Annotation component observable\n */\nexport function mountAnnotationList(\n el: HTMLElement, container: HTMLElement, { target$, print$ }: MountOptions\n): Observable> {\n\n /* Compute prefix for tooltip anchors */\n const parent = container.closest(\"[id]\")\n const prefix = parent?.id\n\n /* Find and replace all markers with empty annotations */\n const annotations = new Map()\n for (const marker of findAnnotationMarkers(container)) {\n const [, id] = marker.textContent!.match(/\\((\\d+)\\)/)!\n if (getOptionalElement(`li:nth-child(${id})`, el)) {\n annotations.set(id, renderAnnotation(id, prefix))\n marker.replaceWith(annotations.get(id)!)\n }\n }\n\n /* Keep list if there are no annotations to render */\n if (annotations.size === 0)\n return EMPTY\n\n /* Mount component on subscription */\n return defer(() => {\n const done$ = new Subject()\n\n /* Retrieve container pairs for swapping */\n const pairs: [HTMLElement, HTMLElement][] = []\n for (const [id, annotation] of annotations)\n pairs.push([\n getElement(\".md-typeset\", annotation),\n getElement(`li:nth-child(${id})`, el)\n ])\n\n /* Handle print mode - see https://bit.ly/3rgPdpt */\n print$\n .pipe(\n takeUntil(done$.pipe(takeLast(1)))\n )\n .subscribe(active => {\n el.hidden = !active\n\n /* Show annotations in code block or list (print) */\n for (const [inner, child] of pairs)\n if (!active)\n swap(child, inner)\n else\n swap(inner, child)\n })\n\n /* Create and return component */\n return merge(...[...annotations]\n .map(([, annotation]) => (\n mountAnnotation(annotation, container, { target$ })\n ))\n )\n .pipe(\n finalize(() => done$.complete()),\n share()\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { watchScript } from \"~/browser\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../../_\"\n\nimport themeCSS from \"./index.css\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid diagram\n */\nexport interface Mermaid {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Mermaid instance observable\n */\nlet mermaid$: Observable\n\n/**\n * Global sequence number for diagrams\n */\nlet sequence = 0\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch Mermaid script\n *\n * @returns Mermaid scripts observable\n */\nfunction fetchScripts(): Observable {\n return typeof mermaid === \"undefined\" || mermaid instanceof Element\n ? watchScript(\"https://unpkg.com/mermaid@9.1.7/dist/mermaid.min.js\")\n : of(undefined)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount Mermaid diagram\n *\n * @param el - Code block element\n *\n * @returns Mermaid diagram component observable\n */\nexport function mountMermaid(\n el: HTMLElement\n): Observable> {\n el.classList.remove(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n mermaid$ ||= fetchScripts()\n .pipe(\n tap(() => mermaid.initialize({\n startOnLoad: false,\n themeCSS,\n sequence: {\n actorFontSize: \"16px\", // Hack: mitigate https://bit.ly/3y0NEi3\n messageFontSize: \"16px\",\n noteFontSize: \"16px\"\n }\n })),\n map(() => undefined),\n shareReplay(1)\n )\n\n /* Render diagram */\n mermaid$.subscribe(() => {\n el.classList.add(\"mermaid\") // Hack: mitigate https://bit.ly/3CiN6Du\n const id = `__mermaid_${sequence++}`\n const host = h(\"div\", { class: \"mermaid\" })\n mermaid.mermaidAPI.render(id, el.textContent, (svg: string) => {\n\n /* Create a shadow root and inject diagram */\n const shadow = host.attachShadow({ mode: \"closed\" })\n shadow.innerHTML = svg\n\n /* Replace code block with diagram */\n el.replaceWith(host)\n })\n })\n\n /* Create and return component */\n return mermaid$\n .pipe(\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n filter,\n finalize,\n map,\n merge,\n tap\n} from \"rxjs\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Details\n */\nexport interface Details {\n action: \"open\" | \"close\" /* Details state */\n reveal?: boolean /* Details is revealed */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch details\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details observable\n */\nexport function watchDetails(\n el: HTMLDetailsElement, { target$, print$ }: WatchOptions\n): Observable
    {\n let open = true\n return merge(\n\n /* Open and focus details on location target */\n target$\n .pipe(\n map(target => target.closest(\"details:not([open])\")!),\n filter(details => el === details),\n map(() => ({\n action: \"open\", reveal: true\n }) as Details)\n ),\n\n /* Open details on print and close afterwards */\n print$\n .pipe(\n filter(active => active || !open),\n tap(() => open = el.open),\n map(active => ({\n action: active ? \"open\" : \"close\"\n }) as Details)\n )\n )\n}\n\n/**\n * Mount details\n *\n * This function ensures that `details` tags are opened on anchor jumps and\n * prior to printing, so the whole content of the page is visible.\n *\n * @param el - Details element\n * @param options - Options\n *\n * @returns Details component observable\n */\nexport function mountDetails(\n el: HTMLDetailsElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n push$.subscribe(({ action, reveal }) => {\n el.toggleAttribute(\"open\", action === \"open\")\n if (reveal)\n el.scrollIntoView()\n })\n\n /* Create and return component */\n return watchDetails(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, of } from \"rxjs\"\n\nimport { renderTable } from \"~/templates\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Data table\n */\nexport interface DataTable {}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Sentinel for replacement\n */\nconst sentinel = h(\"table\")\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount data table\n *\n * This function wraps a data table in another scrollable container, so it can\n * be smoothly scrolled on smaller screen sizes and won't break the layout.\n *\n * @param el - Data table element\n *\n * @returns Data table component observable\n */\nexport function mountDataTable(\n el: HTMLElement\n): Observable> {\n el.replaceWith(sentinel)\n sentinel.replaceWith(renderTable(el))\n\n /* Create and return component */\n return of({ ref: el })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n asyncScheduler,\n auditTime,\n combineLatest,\n defer,\n finalize,\n fromEvent,\n map,\n merge,\n skip,\n startWith,\n subscribeOn,\n takeLast,\n takeUntil,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n getElement,\n getElementContentOffset,\n getElementContentSize,\n getElementOffset,\n getElementSize,\n getElements,\n watchElementContentOffset,\n watchElementSize\n} from \"~/browser\"\nimport { renderTabbedControl } from \"~/templates\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content tabs\n */\nexport interface ContentTabs {\n active: HTMLLabelElement /* Active tab label */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch content tabs\n *\n * @param el - Content tabs element\n *\n * @returns Content tabs observable\n */\nexport function watchContentTabs(\n el: HTMLElement\n): Observable {\n const inputs = getElements(\":scope > input\", el)\n const initial = inputs.find(input => input.checked) || inputs[0]\n return merge(...inputs.map(input => fromEvent(input, \"change\")\n .pipe(\n map(() => getElement(`label[for=\"${input.id}\"]`))\n )\n ))\n .pipe(\n startWith(getElement(`label[for=\"${initial.id}\"]`)),\n map(active => ({ active }))\n )\n}\n\n/**\n * Mount content tabs\n *\n * This function scrolls the active tab into view. While this functionality is\n * provided by browsers as part of `scrollInfoView`, browsers will always also\n * scroll the vertical axis, which we do not want. Thus, we decided to provide\n * this functionality ourselves.\n *\n * @param el - Content tabs element\n * @param options - Options\n *\n * @returns Content tabs component observable\n */\nexport function mountContentTabs(\n el: HTMLElement, { viewport$ }: MountOptions\n): Observable> {\n\n /* Render content tab previous button for pagination */\n const prev = renderTabbedControl(\"prev\")\n el.append(prev)\n\n /* Render content tab next button for pagination */\n const next = renderTabbedControl(\"next\")\n el.append(next)\n\n /* Mount component on subscription */\n const container = getElement(\".tabbed-labels\", el)\n return defer(() => {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n combineLatest([push$, watchElementSize(el)])\n .pipe(\n auditTime(1, animationFrameScheduler),\n takeUntil(done$)\n )\n .subscribe({\n\n /* Handle emission */\n next([{ active }, size]) {\n const offset = getElementOffset(active)\n const { width } = getElementSize(active)\n\n /* Set tab indicator offset and width */\n el.style.setProperty(\"--md-indicator-x\", `${offset.x}px`)\n el.style.setProperty(\"--md-indicator-width\", `${width}px`)\n\n /* Scroll container to active content tab */\n const content = getElementContentOffset(container)\n if (\n offset.x < content.x ||\n offset.x + width > content.x + size.width\n )\n container.scrollTo({\n left: Math.max(0, offset.x - 16),\n behavior: \"smooth\"\n })\n },\n\n /* Handle complete */\n complete() {\n el.style.removeProperty(\"--md-indicator-x\")\n el.style.removeProperty(\"--md-indicator-width\")\n }\n })\n\n /* Hide content tab buttons on borders */\n combineLatest([\n watchElementContentOffset(container),\n watchElementSize(container)\n ])\n .pipe(\n takeUntil(done$)\n )\n .subscribe(([offset, size]) => {\n const content = getElementContentSize(container)\n prev.hidden = offset.x < 16\n next.hidden = offset.x > content.width - size.width - 16\n })\n\n /* Paginate content tab container on click */\n merge(\n fromEvent(prev, \"click\").pipe(map(() => -1)),\n fromEvent(next, \"click\").pipe(map(() => +1))\n )\n .pipe(\n takeUntil(done$)\n )\n .subscribe(direction => {\n const { width } = getElementSize(container)\n container.scrollBy({\n left: width * direction,\n behavior: \"smooth\"\n })\n })\n\n /* Set up linking of content tabs, if enabled */\n if (feature(\"content.tabs.link\"))\n push$.pipe(\n skip(1),\n withLatestFrom(viewport$)\n )\n .subscribe(([{ active }, { offset }]) => {\n const tab = active.innerText.trim()\n if (active.hasAttribute(\"data-md-switching\")) {\n active.removeAttribute(\"data-md-switching\")\n\n /* Determine viewport offset of active tab */\n } else {\n const y = el.offsetTop - offset.y\n\n /* Passively activate other tabs */\n for (const set of getElements(\"[data-tabs]\"))\n for (const input of getElements(\n \":scope > input\", set\n )) {\n const label = getElement(`label[for=\"${input.id}\"]`)\n if (\n label !== active &&\n label.innerText.trim() === tab\n ) {\n label.setAttribute(\"data-md-switching\", \"\")\n input.click()\n break\n }\n }\n\n /* Bring active tab into view */\n window.scrollTo({\n top: el.offsetTop - y\n })\n\n /* Persist active tabs in local storage */\n const tabs = __md_get(\"__tabs\") || []\n __md_set(\"__tabs\", [...new Set([tab, ...tabs])])\n }\n })\n\n /* Create and return component */\n return watchContentTabs(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n .pipe(\n subscribeOn(asyncScheduler)\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, merge } from \"rxjs\"\n\nimport { Viewport, getElements } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Annotation } from \"../annotation\"\nimport {\n CodeBlock,\n Mermaid,\n mountCodeBlock,\n mountMermaid\n} from \"../code\"\nimport {\n Details,\n mountDetails\n} from \"../details\"\nimport {\n DataTable,\n mountDataTable\n} from \"../table\"\nimport {\n ContentTabs,\n mountContentTabs\n} from \"../tabs\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Content\n */\nexport type Content =\n | Annotation\n | ContentTabs\n | CodeBlock\n | Mermaid\n | DataTable\n | Details\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n target$: Observable /* Location target observable */\n print$: Observable /* Media print observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount content\n *\n * This function mounts all components that are found in the content of the\n * actual article, including code blocks, data tables and details.\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Content component observable\n */\nexport function mountContent(\n el: HTMLElement, { viewport$, target$, print$ }: MountOptions\n): Observable> {\n return merge(\n\n /* Code blocks */\n ...getElements(\"pre:not(.mermaid) > code\", el)\n .map(child => mountCodeBlock(child, { target$, print$ })),\n\n /* Mermaid diagrams */\n ...getElements(\"pre.mermaid\", el)\n .map(child => mountMermaid(child)),\n\n /* Data tables */\n ...getElements(\"table:not([class])\", el)\n .map(child => mountDataTable(child)),\n\n /* Details */\n ...getElements(\"details\", el)\n .map(child => mountDetails(child, { target$, print$ })),\n\n /* Content tabs */\n ...getElements(\"[data-tabs]\", el)\n .map(child => mountContentTabs(child, { viewport$ }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n delay,\n finalize,\n map,\n merge,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Dialog\n */\nexport interface Dialog {\n message: string /* Dialog message */\n active: boolean /* Dialog is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n alert$: Subject /* Alert subject */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch dialog\n *\n * @param _el - Dialog element\n * @param options - Options\n *\n * @returns Dialog observable\n */\nexport function watchDialog(\n _el: HTMLElement, { alert$ }: WatchOptions\n): Observable {\n return alert$\n .pipe(\n switchMap(message => merge(\n of(true),\n of(false).pipe(delay(2000))\n )\n .pipe(\n map(active => ({ message, active }))\n )\n )\n )\n}\n\n/**\n * Mount dialog\n *\n * This function reveals the dialog in the right corner when a new alert is\n * emitted through the subject that is passed as part of the options.\n *\n * @param el - Dialog element\n * @param options - Options\n *\n * @returns Dialog component observable\n */\nexport function mountDialog(\n el: HTMLElement, options: MountOptions\n): Observable> {\n const inner = getElement(\".md-typeset\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ message, active }) => {\n el.classList.toggle(\"md-dialog--active\", active)\n inner.textContent = message\n })\n\n /* Create and return component */\n return watchDialog(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n combineLatestWith,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n of,\n shareReplay,\n startWith,\n switchMap,\n takeLast,\n takeUntil\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchToggle\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Main } from \"../../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface Header {\n height: number /* Header visible height */\n hidden: boolean /* Header is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute whether the header is hidden\n *\n * If the user scrolls past a certain threshold, the header can be hidden when\n * scrolling down, and shown when scrolling up.\n *\n * @param options - Options\n *\n * @returns Toggle observable\n */\nfunction isHidden({ viewport$ }: WatchOptions): Observable {\n if (!feature(\"header.autohide\"))\n return of(false)\n\n /* Compute direction and turning point */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => [a < b, b] as const),\n distinctUntilKeyChanged(0)\n )\n\n /* Compute whether header should be hidden */\n const hidden$ = combineLatest([viewport$, direction$])\n .pipe(\n filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100),\n map(([, [direction]]) => direction),\n distinctUntilChanged()\n )\n\n /* Compute threshold for hiding */\n const search$ = watchToggle(\"search\")\n return combineLatest([viewport$, search$])\n .pipe(\n map(([{ offset }, search]) => offset.y > 400 && !search),\n distinctUntilChanged(),\n switchMap(active => active ? hidden$ : of(false)),\n startWith(false)\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header observable\n */\nexport function watchHeader(\n el: HTMLElement, options: WatchOptions\n): Observable
    {\n return defer(() => combineLatest([\n watchElementSize(el),\n isHidden(options)\n ]))\n .pipe(\n map(([{ height }, hidden]) => ({\n height,\n hidden\n })),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.hidden === b.hidden\n )),\n shareReplay(1)\n )\n}\n\n/**\n * Mount header\n *\n * This function manages the different states of the header, i.e. whether it's\n * hidden or rendered with a shadow. This depends heavily on the main area.\n *\n * @param el - Header element\n * @param options - Options\n *\n * @returns Header component observable\n */\nexport function mountHeader(\n el: HTMLElement, { header$, main$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject
    ()\n const done$ = push$.pipe(takeLast(1))\n push$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n combineLatestWith(header$)\n )\n .subscribe(([{ active }, { hidden }]) => {\n el.classList.toggle(\"md-header--shadow\", active && !hidden)\n el.hidden = hidden\n })\n\n /* Link to main area */\n main$.subscribe(push$)\n\n /* Create and return component */\n return header$\n .pipe(\n takeUntil(done$),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n tap\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElementSize,\n getOptionalElement,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { Header } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface HeaderTitle {\n active: boolean /* Header title is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header title\n *\n * @param el - Heading element\n * @param options - Options\n *\n * @returns Header title observable\n */\nexport function watchHeaderTitle(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchViewportAt(el, { viewport$, header$ })\n .pipe(\n map(({ offset: { y } }) => {\n const { height } = getElementSize(el)\n return {\n active: y >= height\n }\n }),\n distinctUntilKeyChanged(\"active\")\n )\n}\n\n/**\n * Mount header title\n *\n * This function swaps the header title from the site title to the title of the\n * current page when the user scrolls past the first headline.\n *\n * @param el - Header title element\n * @param options - Options\n *\n * @returns Header title component observable\n */\nexport function mountHeaderTitle(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ active }) => {\n el.classList.toggle(\"md-header__title--active\", active)\n })\n\n /* Obtain headline, if any */\n const heading = getOptionalElement(\"article h1\")\n if (typeof heading === \"undefined\")\n return EMPTY\n\n /* Create and return component */\n return watchHeaderTitle(heading, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchElementSize\n} from \"~/browser\"\n\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Main area\n */\nexport interface Main {\n offset: number /* Main area top offset */\n height: number /* Main area visible height */\n active: boolean /* Main area is active */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch main area\n *\n * This function returns an observable that computes the visual parameters of\n * the main area which depends on the viewport vertical offset and height, as\n * well as the height of the header element, if the header is fixed.\n *\n * @param el - Main area element\n * @param options - Options\n *\n * @returns Main area observable\n */\nexport function watchMain(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable
    {\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n map(({ height }) => height),\n distinctUntilChanged()\n )\n\n /* Compute the main area's top and bottom borders */\n const border$ = adjust$\n .pipe(\n switchMap(() => watchElementSize(el)\n .pipe(\n map(({ height }) => ({\n top: el.offsetTop,\n bottom: el.offsetTop + height\n })),\n distinctUntilKeyChanged(\"bottom\")\n )\n )\n )\n\n /* Compute the main area's offset, visible height and if we scrolled past */\n return combineLatest([adjust$, border$, viewport$])\n .pipe(\n map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => {\n height = Math.max(0, height\n - Math.max(0, top - y, header)\n - Math.max(0, height + y - bottom)\n )\n return {\n offset: top - header,\n height,\n active: top - header <= y\n }\n }),\n distinctUntilChanged((a, b) => (\n a.offset === b.offset &&\n a.height === b.height &&\n a.active === b.active\n ))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n defer,\n finalize,\n fromEvent,\n map,\n mergeMap,\n observeOn,\n of,\n shareReplay,\n startWith,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\nimport { Component } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Palette colors\n */\nexport interface PaletteColor {\n scheme?: string /* Color scheme */\n primary?: string /* Primary color */\n accent?: string /* Accent color */\n}\n\n/**\n * Palette\n */\nexport interface Palette {\n index: number /* Palette index */\n color: PaletteColor /* Palette colors */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch color palette\n *\n * @param inputs - Color palette element\n *\n * @returns Color palette observable\n */\nexport function watchPalette(\n inputs: HTMLInputElement[]\n): Observable {\n const current = __md_get(\"__palette\") || {\n index: inputs.findIndex(input => matchMedia(\n input.getAttribute(\"data-md-color-media\")!\n ).matches)\n }\n\n /* Emit changes in color palette */\n return of(...inputs)\n .pipe(\n mergeMap(input => fromEvent(input, \"change\")\n .pipe(\n map(() => input)\n )\n ),\n startWith(inputs[Math.max(0, current.index)]),\n map(input => ({\n index: inputs.indexOf(input),\n color: {\n scheme: input.getAttribute(\"data-md-color-scheme\"),\n primary: input.getAttribute(\"data-md-color-primary\"),\n accent: input.getAttribute(\"data-md-color-accent\")\n }\n } as Palette)),\n shareReplay(1)\n )\n}\n\n/**\n * Mount color palette\n *\n * @param el - Color palette element\n *\n * @returns Color palette component observable\n */\nexport function mountPalette(\n el: HTMLElement\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(palette => {\n document.body.setAttribute(\"data-md-color-switching\", \"\")\n\n /* Set color palette */\n for (const [key, value] of Object.entries(palette.color))\n document.body.setAttribute(`data-md-color-${key}`, value)\n\n /* Toggle visibility */\n for (let index = 0; index < inputs.length; index++) {\n const label = inputs[index].nextElementSibling\n if (label instanceof HTMLElement)\n label.hidden = palette.index !== index\n }\n\n /* Persist preference in local storage */\n __md_set(\"__palette\", palette)\n })\n\n /* Revert transition durations after color switch */\n push$.pipe(observeOn(asyncScheduler))\n .subscribe(() => {\n document.body.removeAttribute(\"data-md-color-switching\")\n })\n\n /* Create and return component */\n const inputs = getElements(\"input\", el)\n return watchPalette(inputs)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ClipboardJS from \"clipboard\"\nimport {\n Observable,\n Subject,\n map,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport { getElement } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n alert$: Subject /* Alert subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Extract text to copy\n *\n * @param el - HTML element\n *\n * @returns Extracted text\n */\nfunction extract(el: HTMLElement): string {\n el.setAttribute(\"data-md-copying\", \"\")\n const text = el.innerText\n el.removeAttribute(\"data-md-copying\")\n return text\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up Clipboard.js integration\n *\n * @param options - Options\n */\nexport function setupClipboardJS(\n { alert$ }: SetupOptions\n): void {\n if (ClipboardJS.isSupported()) {\n new Observable(subscriber => {\n new ClipboardJS(\"[data-clipboard-target], [data-clipboard-text]\", {\n text: el => (\n el.getAttribute(\"data-clipboard-text\")! ||\n extract(getElement(\n el.getAttribute(\"data-clipboard-target\")!\n ))\n )\n })\n .on(\"success\", ev => subscriber.next(ev))\n })\n .pipe(\n tap(ev => {\n const trigger = ev.trigger as HTMLElement\n trigger.focus()\n }),\n map(() => translation(\"clipboard.copied\"))\n )\n .subscribe(alert$)\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map,\n of,\n tap\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport { getElements, requestXML } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sitemap, i.e. a list of URLs\n */\nexport type Sitemap = string[]\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Preprocess a list of URLs\n *\n * This function replaces the `site_url` in the sitemap with the actual base\n * URL, to allow instant loading to work in occasions like Netlify previews.\n *\n * @param urls - URLs\n *\n * @returns URL path parts\n */\nfunction preprocess(urls: Sitemap): Sitemap {\n if (urls.length < 2)\n return [\"\"]\n\n /* Take the first two URLs and remove everything after the last slash */\n const [root, next] = [...urls]\n .sort((a, b) => a.length - b.length)\n .map(url => url.replace(/[^/]+$/, \"\"))\n\n /* Compute common prefix */\n let index = 0\n if (root === next)\n index = root.length\n else\n while (root.charCodeAt(index) === next.charCodeAt(index))\n index++\n\n /* Remove common prefix and return in original order */\n return urls.map(url => url.replace(root.slice(0, index), \"\"))\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch the sitemap for the given base URL\n *\n * @param base - Base URL\n *\n * @returns Sitemap observable\n */\nexport function fetchSitemap(base?: URL): Observable {\n const cached = __md_get(\"__sitemap\", sessionStorage, base)\n if (cached) {\n return of(cached)\n } else {\n const config = configuration()\n return requestXML(new URL(\"sitemap.xml\", base || config.base))\n .pipe(\n map(sitemap => preprocess(getElements(\"loc\", sitemap)\n .map(node => node.textContent!)\n )),\n catchError(() => EMPTY), // @todo refactor instant loading\n defaultIfEmpty([]),\n tap(sitemap => __md_set(\"__sitemap\", sitemap, sessionStorage, base))\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n bufferCount,\n catchError,\n concatMap,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n fromEvent,\n map,\n merge,\n of,\n sample,\n share,\n skip,\n skipUntil,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"~/_\"\nimport {\n Viewport,\n ViewportOffset,\n getElements,\n getOptionalElement,\n request,\n setLocation,\n setLocationHash\n} from \"~/browser\"\nimport { getComponentElement } from \"~/components\"\nimport { h } from \"~/utilities\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * History state\n */\nexport interface HistoryState {\n url: URL /* State URL */\n offset?: ViewportOffset /* State viewport offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n location$: Subject /* Location subject */\n viewport$: Observable /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up instant loading\n *\n * When fetching, theoretically, we could use `responseType: \"document\"`, but\n * since all MkDocs links are relative, we need to make sure that the current\n * location matches the document we just loaded. Otherwise any relative links\n * in the document could use the old location.\n *\n * This is the reason why we need to synchronize history events and the process\n * of fetching the document for navigation changes (except `popstate` events):\n *\n * 1. Fetch document via `XMLHTTPRequest`\n * 2. Set new location via `history.pushState`\n * 3. Parse and emit fetched document\n *\n * For `popstate` events, we must not use `history.pushState`, or the forward\n * history will be irreversibly overwritten. In case the request fails, the\n * location change is dispatched regularly.\n *\n * @param options - Options\n */\nexport function setupInstantLoading(\n { document$, location$, viewport$ }: SetupOptions\n): void {\n const config = configuration()\n if (location.protocol === \"file:\")\n return\n\n /* Disable automatic scroll restoration */\n if (\"scrollRestoration\" in history) {\n history.scrollRestoration = \"manual\"\n\n /* Hack: ensure that reloads restore viewport offset */\n fromEvent(window, \"beforeunload\")\n .subscribe(() => {\n history.scrollRestoration = \"auto\"\n })\n }\n\n /* Hack: ensure absolute favicon link to omit 404s when switching */\n const favicon = getOptionalElement(\"link[rel=icon]\")\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href\n\n /* Intercept internal navigation */\n const push$ = fetchSitemap()\n .pipe(\n map(paths => paths.map(path => `${new URL(path, config.base)}`)),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n switchMap(ev => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target) {\n const url = new URL(el.href)\n\n /* Canonicalize URL */\n url.search = \"\"\n url.hash = \"\"\n\n /* Check if URL should be intercepted */\n if (\n url.pathname !== location.pathname &&\n urls.includes(url.toString())\n ) {\n ev.preventDefault()\n return of({\n url: new URL(el.href)\n })\n }\n }\n }\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Intercept history back and forward */\n const pop$ = fromEvent(window, \"popstate\")\n .pipe(\n filter(ev => ev.state !== null),\n map(ev => ({\n url: new URL(location.href),\n offset: ev.state\n })),\n share()\n )\n\n /* Emit location change */\n merge(push$, pop$)\n .pipe(\n distinctUntilChanged((a, b) => a.url.href === b.url.href),\n map(({ url }) => url)\n )\n .subscribe(location$)\n\n /* Fetch document via `XMLHTTPRequest` */\n const response$ = location$\n .pipe(\n distinctUntilKeyChanged(\"pathname\"),\n switchMap(url => request(url.href)\n .pipe(\n catchError(() => {\n setLocation(url)\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Set new location via `history.pushState` */\n push$\n .pipe(\n sample(response$)\n )\n .subscribe(({ url }) => {\n history.pushState({}, \"\", `${url}`)\n })\n\n /* Parse and emit fetched document */\n const dom = new DOMParser()\n response$\n .pipe(\n switchMap(res => res.text()),\n map(res => dom.parseFromString(res, \"text/html\"))\n )\n .subscribe(document$)\n\n /* Replace meta tags and components */\n document$\n .pipe(\n skip(1)\n )\n .subscribe(replacement => {\n for (const selector of [\n\n /* Meta tags */\n \"title\",\n \"link[rel=canonical]\",\n \"meta[name=author]\",\n \"meta[name=description]\",\n\n /* Components */\n \"[data-md-component=announce]\",\n \"[data-md-component=container]\",\n \"[data-md-component=header-topic]\",\n \"[data-md-component=outdated]\",\n \"[data-md-component=logo]\",\n \"[data-md-component=skip]\",\n ...feature(\"navigation.tabs.sticky\")\n ? [\"[data-md-component=tabs]\"]\n : []\n ]) {\n const source = getOptionalElement(selector)\n const target = getOptionalElement(selector, replacement)\n if (\n typeof source !== \"undefined\" &&\n typeof target !== \"undefined\"\n ) {\n source.replaceWith(target)\n }\n }\n })\n\n /* Re-evaluate scripts */\n document$\n .pipe(\n skip(1),\n map(() => getComponentElement(\"container\")),\n switchMap(el => getElements(\"script\", el)),\n concatMap(el => {\n const script = h(\"script\")\n if (el.src) {\n for (const name of el.getAttributeNames())\n script.setAttribute(name, el.getAttribute(name)!)\n el.replaceWith(script)\n\n /* Complete when script is loaded */\n return new Observable(observer => {\n script.onload = () => observer.complete()\n })\n\n /* Complete immediately */\n } else {\n script.textContent = el.textContent\n el.replaceWith(script)\n return EMPTY\n }\n })\n )\n .subscribe()\n\n /* Emit history state change */\n merge(push$, pop$)\n .pipe(\n sample(document$)\n )\n .subscribe(({ url, offset }) => {\n if (url.hash && !offset) {\n setLocationHash(url.hash)\n } else {\n window.scrollTo(0, offset?.y || 0)\n }\n })\n\n /* Debounce update of viewport offset */\n viewport$\n .pipe(\n skipUntil(push$),\n debounceTime(250),\n distinctUntilKeyChanged(\"offset\")\n )\n .subscribe(({ offset }) => {\n history.replaceState(offset, \"\")\n })\n\n /* Set viewport offset from history */\n merge(push$, pop$)\n .pipe(\n bufferCount(2, 1),\n filter(([a, b]) => a.url.pathname === b.url.pathname),\n map(([, state]) => state)\n )\n .subscribe(({ offset }) => {\n window.scrollTo(0, offset?.y || 0)\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search transformation function\n *\n * @param value - Query value\n *\n * @returns Transformed query value\n */\nexport type SearchTransformFn = (value: string) => string\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Default transformation function\n *\n * 1. Search for terms in quotation marks and prepend a `+` modifier to denote\n * that the resulting document must contain all terms, converting the query\n * to an `AND` query (as opposed to the default `OR` behavior). While users\n * may expect terms enclosed in quotation marks to map to span queries, i.e.\n * for which order is important, Lunr.js doesn't support them, so the best\n * we can do is to convert the terms to an `AND` query.\n *\n * 2. Replace control characters which are not located at the beginning of the\n * query or preceded by white space, or are not followed by a non-whitespace\n * character or are at the end of the query string. Furthermore, filter\n * unmatched quotation marks.\n *\n * 3. Trim excess whitespace from left and right.\n *\n * @param query - Query value\n *\n * @returns Transformed query value\n */\nexport function defaultTransform(query: string): string {\n return query\n .split(/\"([^\"]+)\"/g) /* => 1 */\n .map((terms, index) => index & 1\n ? terms.replace(/^\\b|^(?![^\\x00-\\x7F]|$)|\\s+/g, \" +\")\n : terms\n )\n .join(\"\")\n .replace(/\"|(?:^|\\s+)[*+\\-:^~]+(?=\\s+|$)/g, \"\") /* => 2 */\n .trim() /* => 3 */\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndex, SearchResult } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search message type\n */\nexport const enum SearchMessageType {\n SETUP, /* Search index setup */\n READY, /* Search index ready */\n QUERY, /* Search query */\n RESULT /* Search results */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message containing the data necessary to setup the search index\n */\nexport interface SearchSetupMessage {\n type: SearchMessageType.SETUP /* Message type */\n data: SearchIndex /* Message data */\n}\n\n/**\n * Message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * Message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * Message containing results for a search query\n */\nexport interface SearchResultMessage {\n type: SearchMessageType.RESULT /* Message type */\n data: SearchResult /* Message data */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Message exchanged with the search worker\n */\nexport type SearchMessage =\n | SearchSetupMessage\n | SearchReadyMessage\n | SearchQueryMessage\n | SearchResultMessage\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Type guard for search setup messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchSetupMessage(\n message: SearchMessage\n): message is SearchSetupMessage {\n return message.type === SearchMessageType.SETUP\n}\n\n/**\n * Type guard for search ready messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchReadyMessage(\n message: SearchMessage\n): message is SearchReadyMessage {\n return message.type === SearchMessageType.READY\n}\n\n/**\n * Type guard for search query messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchQueryMessage(\n message: SearchMessage\n): message is SearchQueryMessage {\n return message.type === SearchMessageType.QUERY\n}\n\n/**\n * Type guard for search result messages\n *\n * @param message - Search worker message\n *\n * @returns Test result\n */\nexport function isSearchResultMessage(\n message: SearchMessage\n): message is SearchResultMessage {\n return message.type === SearchMessageType.RESULT\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n ObservableInput,\n Subject,\n from,\n map,\n share\n} from \"rxjs\"\n\nimport { configuration, feature, translation } from \"~/_\"\nimport { WorkerHandler, watchWorker } from \"~/browser\"\n\nimport { SearchIndex } from \"../../_\"\nimport {\n SearchOptions,\n SearchPipeline\n} from \"../../options\"\nimport {\n SearchMessage,\n SearchMessageType,\n SearchSetupMessage,\n isSearchResultMessage\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search worker\n */\nexport type SearchWorker = WorkerHandler\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search index\n *\n * @param data - Search index\n *\n * @returns Search index\n */\nfunction setupSearchIndex({ config, docs }: SearchIndex): SearchIndex {\n\n /* Override default language with value from translation */\n if (config.lang.length === 1 && config.lang[0] === \"en\")\n config.lang = [\n translation(\"search.config.lang\")\n ]\n\n /* Override default separator with value from translation */\n if (config.separator === \"[\\\\s\\\\-]+\")\n config.separator = translation(\"search.config.separator\")\n\n /* Set pipeline from translation */\n const pipeline = translation(\"search.config.pipeline\")\n .split(/\\s*,\\s*/)\n .filter(Boolean) as SearchPipeline\n\n /* Determine search options */\n const options: SearchOptions = {\n pipeline,\n suggestions: feature(\"search.suggest\")\n }\n\n /* Return search index after defaulting */\n return { config, docs, options }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search worker\n *\n * This function creates a web worker to set up and query the search index,\n * which is done using Lunr.js. The index must be passed as an observable to\n * enable hacks like _localsearch_ via search index embedding as JSON.\n *\n * @param url - Worker URL\n * @param index - Search index observable input\n *\n * @returns Search worker\n */\nexport function setupSearchWorker(\n url: string, index: ObservableInput\n): SearchWorker {\n const config = configuration()\n const worker = new Worker(url)\n\n /* Create communication channels and resolve relative links */\n const tx$ = new Subject()\n const rx$ = watchWorker(worker, { tx$ })\n .pipe(\n map(message => {\n if (isSearchResultMessage(message)) {\n for (const result of message.data.items)\n for (const document of result)\n document.location = `${new URL(document.location, config.base)}`\n }\n return message\n }),\n share()\n )\n\n /* Set up search index */\n from(index)\n .pipe(\n map(data => ({\n type: SearchMessageType.SETUP,\n data: setupSearchIndex(data)\n } as SearchSetupMessage))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return search worker */\n return { tx$, rx$ }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Subject,\n catchError,\n combineLatest,\n filter,\n fromEvent,\n map,\n of,\n switchMap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n getElement,\n getLocation,\n requestJSON,\n setLocation\n} from \"~/browser\"\nimport { getComponentElements } from \"~/components\"\nimport {\n Version,\n renderVersionSelector\n} from \"~/templates\"\n\nimport { fetchSitemap } from \"../sitemap\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject /* Document subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up version selector\n *\n * @param options - Options\n */\nexport function setupVersionSelector(\n { document$ }: SetupOptions\n): void {\n const config = configuration()\n const versions$ = requestJSON(\n new URL(\"../versions.json\", config.base)\n )\n .pipe(\n catchError(() => EMPTY) // @todo refactor instant loading\n )\n\n /* Determine current version */\n const current$ = versions$\n .pipe(\n map(versions => {\n const [, current] = config.base.match(/([^/]+)\\/?$/)!\n return versions.find(({ version, aliases }) => (\n version === current || aliases.includes(current)\n )) || versions[0]\n })\n )\n\n /* Intercept inter-version navigation */\n versions$\n .pipe(\n map(versions => new Map(versions.map(version => [\n `${new URL(`../${version.version}/`, config.base)}`,\n version\n ]))),\n switchMap(urls => fromEvent(document.body, \"click\")\n .pipe(\n filter(ev => !ev.metaKey && !ev.ctrlKey),\n withLatestFrom(current$),\n switchMap(([ev, current]) => {\n if (ev.target instanceof Element) {\n const el = ev.target.closest(\"a\")\n if (el && !el.target && urls.has(el.href)) {\n const url = el.href\n // This is a temporary hack to detect if a version inside the\n // version selector or on another part of the site was clicked.\n // If we're inside the version selector, we definitely want to\n // find the same page, as we might have different deployments\n // due to aliases. However, if we're outside the version\n // selector, we must abort here, because we might otherwise\n // interfere with instant loading. We need to refactor this\n // at some point together with instant loading.\n //\n // See https://github.com/squidfunk/mkdocs-material/issues/4012\n if (!ev.target.closest(\".md-version\")) {\n const version = urls.get(url)!\n if (version === current)\n return EMPTY\n }\n ev.preventDefault()\n return of(url)\n }\n }\n return EMPTY\n }),\n switchMap(url => {\n const { version } = urls.get(url)!\n return fetchSitemap(new URL(url))\n .pipe(\n map(sitemap => {\n const location = getLocation()\n const path = location.href.replace(config.base, \"\")\n return sitemap.includes(path.split(\"#\")[0])\n ? new URL(`../${version}/${path}`, config.base)\n : new URL(url)\n })\n )\n })\n )\n )\n )\n .subscribe(url => setLocation(url))\n\n /* Render version selector and warning */\n combineLatest([versions$, current$])\n .subscribe(([versions, current]) => {\n const topic = getElement(\".md-header__topic\")\n topic.appendChild(renderVersionSelector(versions, current))\n })\n\n /* Integrate outdated version banner with instant loading */\n document$.pipe(switchMap(() => current$))\n .subscribe(current => {\n\n /* Check if version state was already determined */\n let outdated = __md_get(\"__outdated\", sessionStorage)\n if (outdated === null) {\n const latest = config.version?.default || \"latest\"\n outdated = !current.aliases.includes(latest)\n\n /* Persist version state in session storage */\n __md_set(\"__outdated\", outdated, sessionStorage)\n }\n\n /* Unhide outdated version banner */\n if (outdated)\n for (const warning of getComponentElements(\"outdated\"))\n warning.hidden = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n combineLatest,\n delay,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n share,\n shareReplay,\n startWith,\n take,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getLocation,\n setToggle,\n watchElementFocus,\n watchToggle\n} from \"~/browser\"\nimport {\n SearchMessageType,\n SearchQueryMessage,\n SearchWorker,\n defaultTransform,\n isSearchReadyMessage\n} from \"~/integrations\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query\n */\nexport interface SearchQuery {\n value: string /* Query value */\n focus: boolean /* Query focus */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search query\n *\n * Note that the focus event which triggers re-reading the current query value\n * is delayed by `1ms` so the input's empty state is allowed to propagate.\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement, { rx$ }: SearchWorker\n): Observable {\n const fn = __search?.transform || defaultTransform\n\n /* Immediately show search dialog */\n const { searchParams } = getLocation()\n if (searchParams.has(\"q\"))\n setToggle(\"search\", true)\n\n /* Intercept query parameter (deep link) */\n const param$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1),\n map(() => searchParams.get(\"q\") || \"\")\n )\n\n /* Remove query parameter when search is closed */\n watchToggle(\"search\")\n .pipe(\n filter(active => !active),\n take(1)\n )\n .subscribe(() => {\n const url = new URL(location.href)\n url.searchParams.delete(\"q\")\n history.replaceState({}, \"\", `${url}`)\n })\n\n /* Set query from parameter */\n param$.subscribe(value => { // TODO: not ideal - find a better way\n if (value) {\n el.value = value\n el.focus()\n }\n })\n\n /* Intercept focus and input events */\n const focus$ = watchElementFocus(el)\n const value$ = merge(\n fromEvent(el, \"keyup\"),\n fromEvent(el, \"focus\").pipe(delay(1)),\n param$\n )\n .pipe(\n map(() => fn(el.value)),\n startWith(\"\"),\n distinctUntilChanged(),\n )\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount search query\n *\n * @param el - Search query element\n * @param worker - Search worker\n *\n * @returns Search query component observable\n */\nexport function mountSearchQuery(\n el: HTMLInputElement, { tx$, rx$ }: SearchWorker\n): Observable> {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n\n /* Handle value changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"value\"),\n map(({ value }): SearchQueryMessage => ({\n type: SearchMessageType.QUERY,\n data: value\n }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Handle focus changes */\n push$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus) {\n setToggle(\"search\", focus)\n el.placeholder = \"\"\n } else {\n el.placeholder = translation(\"search.placeholder\")\n }\n })\n\n /* Handle reset */\n fromEvent(el.form!, \"reset\")\n .pipe(\n takeUntil(done$)\n )\n .subscribe(() => el.focus())\n\n /* Create and return component */\n return watchSearchQuery(el, { tx$, rx$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state })),\n share()\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n filter,\n finalize,\n map,\n merge,\n of,\n skipUntil,\n switchMap,\n take,\n tap,\n withLatestFrom,\n zipWith\n} from \"rxjs\"\n\nimport { translation } from \"~/_\"\nimport {\n getElement,\n watchElementBoundary\n} from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchReadyMessage,\n isSearchResultMessage\n} from \"~/integrations\"\nimport { renderSearchResultItem } from \"~/templates\"\nimport { round } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search result list\n *\n * This function performs a lazy rendering of the search results, depending on\n * the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchResult(\n el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n const boundary$ = watchElementBoundary(el.parentElement!)\n .pipe(\n filter(Boolean)\n )\n\n /* Retrieve nested components */\n const meta = getElement(\":scope > :first-child\", el)\n const list = getElement(\":scope > :last-child\", el)\n\n /* Wait until search is ready */\n const ready$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n take(1)\n )\n\n /* Update search result metadata */\n push$\n .pipe(\n withLatestFrom(query$),\n skipUntil(ready$)\n )\n .subscribe(([{ items }, { value }]) => {\n if (value) {\n switch (items.length) {\n\n /* No results */\n case 0:\n meta.textContent = translation(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n meta.textContent = translation(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n meta.textContent = translation(\n \"search.result.other\",\n round(items.length)\n )\n }\n } else {\n meta.textContent = translation(\"search.result.placeholder\")\n }\n })\n\n /* Update search result list */\n push$\n .pipe(\n tap(() => list.innerHTML = \"\"),\n switchMap(({ items }) => merge(\n of(...items.slice(0, 10)),\n of(...items.slice(10))\n .pipe(\n bufferCount(4),\n zipWith(boundary$),\n switchMap(([chunk]) => chunk)\n )\n ))\n )\n .subscribe(result => list.appendChild(\n renderSearchResultItem(result)\n ))\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n finalize,\n fromEvent,\n map,\n tap\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\n\nimport { Component } from \"../../_\"\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search sharing\n */\nexport interface SearchShare {\n url: URL /* Deep link for sharing */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n query$: Observable /* Search query observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search sharing\n *\n * @param _el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing observable\n */\nexport function watchSearchShare(\n _el: HTMLElement, { query$ }: WatchOptions\n): Observable {\n return query$\n .pipe(\n map(({ value }) => {\n const url = getLocation()\n url.hash = \"\"\n url.searchParams.delete(\"h\")\n url.searchParams.set(\"q\", value)\n return { url }\n })\n )\n}\n\n/**\n * Mount search sharing\n *\n * @param el - Search sharing element\n * @param options - Options\n *\n * @returns Search sharing component observable\n */\nexport function mountSearchShare(\n el: HTMLAnchorElement, options: MountOptions\n): Observable> {\n const push$ = new Subject()\n push$.subscribe(({ url }) => {\n el.setAttribute(\"data-clipboard-text\", el.href)\n el.href = `${url}`\n })\n\n /* Prevent following of link */\n fromEvent(el, \"click\")\n .subscribe(ev => ev.preventDefault())\n\n /* Create and return component */\n return watchSearchShare(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n asyncScheduler,\n combineLatestWith,\n distinctUntilChanged,\n filter,\n finalize,\n fromEvent,\n map,\n merge,\n observeOn,\n tap\n} from \"rxjs\"\n\nimport { Keyboard } from \"~/browser\"\nimport {\n SearchResult,\n SearchWorker,\n isSearchResultMessage\n} from \"~/integrations\"\n\nimport { Component, getComponentElement } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search suggestions\n */\nexport interface SearchSuggest {}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search suggestions\n *\n * This function will perform a lazy rendering of the search results, depending\n * on the vertical offset of the search result container.\n *\n * @param el - Search result list element\n * @param worker - Search worker\n * @param options - Options\n *\n * @returns Search result list component observable\n */\nexport function mountSearchSuggest(\n el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n\n /* Retrieve query component and track all changes */\n const query = getComponentElement(\"search-query\")\n const query$ = merge(\n fromEvent(query, \"keydown\"),\n fromEvent(query, \"focus\")\n )\n .pipe(\n observeOn(asyncScheduler),\n map(() => query.value),\n distinctUntilChanged(),\n )\n\n /* Update search suggestions */\n push$\n .pipe(\n combineLatestWith(query$),\n map(([{ suggestions }, value]) => {\n const words = value.split(/([\\s-]+)/)\n if (suggestions?.length && words[words.length - 1]) {\n const last = suggestions[suggestions.length - 1]\n if (last.startsWith(words[words.length - 1]))\n words[words.length - 1] = last\n } else {\n words.length = 0\n }\n return words\n })\n )\n .subscribe(words => el.innerHTML = words\n .join(\"\")\n .replace(/\\s/g, \" \")\n )\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Right arrow: accept current suggestion */\n case \"ArrowRight\":\n if (\n el.innerText.length &&\n query.selectionStart === query.value.length\n )\n query.value = el.innerText\n break\n }\n })\n\n /* Filter search result message */\n const result$ = rx$\n .pipe(\n filter(isSearchResultMessage),\n map(({ data }) => data)\n )\n\n /* Create and return component */\n return result$\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(() => ({ ref: el }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n Observable,\n ObservableInput,\n filter,\n merge,\n mergeWith,\n sample,\n take\n} from \"rxjs\"\n\nimport { configuration } from \"~/_\"\nimport {\n Keyboard,\n getActiveElement,\n getElements,\n setToggle\n} from \"~/browser\"\nimport {\n SearchIndex,\n SearchResult,\n isSearchQueryMessage,\n isSearchReadyMessage,\n setupSearchWorker\n} from \"~/integrations\"\n\nimport {\n Component,\n getComponentElement,\n getComponentElements\n} from \"../../_\"\nimport {\n SearchQuery,\n mountSearchQuery\n} from \"../query\"\nimport { mountSearchResult } from \"../result\"\nimport {\n SearchShare,\n mountSearchShare\n} from \"../share\"\nimport {\n SearchSuggest,\n mountSearchSuggest\n} from \"../suggest\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport type Search =\n | SearchQuery\n | SearchResult\n | SearchShare\n | SearchSuggest\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n keyboard$: Observable /* Keyboard observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search\n *\n * This function sets up the search functionality, including the underlying\n * web worker and all keyboard bindings.\n *\n * @param el - Search element\n * @param options - Options\n *\n * @returns Search component observable\n */\nexport function mountSearch(\n el: HTMLElement, { index$, keyboard$ }: MountOptions\n): Observable> {\n const config = configuration()\n try {\n const url = __search?.worker || config.search\n const worker = setupSearchWorker(url, index$)\n\n /* Retrieve query and result components */\n const query = getComponentElement(\"search-query\", el)\n const result = getComponentElement(\"search-result\", el)\n\n /* Re-emit query when search is ready */\n const { tx$, rx$ } = worker\n tx$\n .pipe(\n filter(isSearchQueryMessage),\n sample(rx$.pipe(filter(isSearchReadyMessage))),\n take(1)\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\")\n )\n .subscribe(key => {\n const active = getActiveElement()\n switch (key.type) {\n\n /* Enter: go to first (best) result */\n case \"Enter\":\n if (active === query) {\n const anchors = new Map()\n for (const anchor of getElements(\n \":first-child [href]\", result\n )) {\n const article = anchor.firstElementChild!\n anchors.set(anchor, parseFloat(\n article.getAttribute(\"data-md-score\")!\n ))\n }\n\n /* Go to result with highest score, if any */\n if (anchors.size) {\n const [[best]] = [...anchors].sort(([, a], [, b]) => b - a)\n best.click()\n }\n\n /* Otherwise omit form submission */\n key.claim()\n }\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n query.blur()\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n query.focus()\n } else {\n const els = [query, ...getElements(\n \":not(details) > [href], summary, details[open] [href]\",\n result\n )]\n const i = Math.max(0, (\n Math.max(0, els.indexOf(active)) + els.length + (\n key.type === \"ArrowUp\" ? -1 : +1\n )\n ) % els.length)\n els[i].focus()\n }\n\n /* Prevent scrolling of page */\n key.claim()\n break\n\n /* All other keys: hand to search query */\n default:\n if (query !== getActiveElement())\n query.focus()\n }\n })\n\n /* Set up global keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\"),\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Open search and select query */\n case \"f\":\n case \"s\":\n case \"/\":\n query.focus()\n query.select()\n\n /* Prevent scrolling of page */\n key.claim()\n break\n }\n })\n\n /* Create and return component */\n const query$ = mountSearchQuery(query, worker)\n const result$ = mountSearchResult(result, worker, { query$ })\n return merge(query$, result$)\n .pipe(\n mergeWith(\n\n /* Search sharing */\n ...getComponentElements(\"search-share\", el)\n .map(child => mountSearchShare(child, { query$ })),\n\n /* Search suggestions */\n ...getComponentElements(\"search-suggest\", el)\n .map(child => mountSearchSuggest(child, worker, { keyboard$ }))\n )\n )\n\n /* Gracefully handle broken search */\n } catch (err) {\n el.hidden = true\n return NEVER\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n ObservableInput,\n combineLatest,\n filter,\n map,\n startWith\n} from \"rxjs\"\n\nimport { getLocation } from \"~/browser\"\nimport {\n SearchIndex,\n setupSearchHighlighter\n} from \"~/integrations\"\nimport { h } from \"~/utilities\"\n\nimport { Component } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlighting\n */\nexport interface SearchHighlight {\n nodes: Map /* Map of replacements */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n index$: ObservableInput /* Search index observable */\n location$: Observable /* Location observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search highlighting\n *\n * @param el - Content element\n * @param options - Options\n *\n * @returns Search highlighting component observable\n */\nexport function mountSearchHiglight(\n el: HTMLElement, { index$, location$ }: MountOptions\n): Observable> {\n return combineLatest([\n index$,\n location$\n .pipe(\n startWith(getLocation()),\n filter(url => !!url.searchParams.get(\"h\"))\n )\n ])\n .pipe(\n map(([index, url]) => setupSearchHighlighter(index.config, true)(\n url.searchParams.get(\"h\")!\n )),\n map(fn => {\n const nodes = new Map()\n\n /* Traverse text nodes and collect matches */\n const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT)\n for (let node = it.nextNode(); node; node = it.nextNode()) {\n if (node.parentElement?.offsetHeight) {\n const original = node.textContent!\n const replaced = fn(original)\n if (replaced.length > original.length)\n nodes.set(node as ChildNode, replaced)\n }\n }\n\n /* Replace original nodes with matches */\n for (const [node, text] of nodes) {\n const { childNodes } = h(\"span\", null, text)\n node.replaceWith(...Array.from(childNodes))\n }\n\n /* Return component */\n return { ref: el, nodes }\n })\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n animationFrameScheduler,\n auditTime,\n combineLatest,\n defer,\n distinctUntilChanged,\n finalize,\n map,\n observeOn,\n take,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n getElement,\n getElementContainer,\n getElementOffset,\n getElementSize,\n getElements\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Sidebar\n */\nexport interface Sidebar {\n height: number /* Sidebar height */\n locked: boolean /* Sidebar is locked */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch sidebar\n *\n * This function returns an observable that computes the visual parameters of\n * the sidebar which depends on the vertical viewport offset, as well as the\n * height of the main area. When the page is scrolled beyond the header, the\n * sidebar is locked and fills the remaining space.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar observable\n */\nexport function watchSidebar(\n el: HTMLElement, { viewport$, main$ }: WatchOptions\n): Observable {\n const parent = el.parentElement!\n const adjust =\n parent.offsetTop -\n parent.parentElement!.offsetTop\n\n /* Compute the sidebar's available height and if it should be locked */\n return combineLatest([main$, viewport$])\n .pipe(\n map(([{ offset, height }, { offset: { y } }]) => {\n height = height\n + Math.min(adjust, Math.max(0, y - offset))\n - adjust\n return {\n height,\n locked: y >= offset + adjust\n }\n }),\n distinctUntilChanged((a, b) => (\n a.height === b.height &&\n a.locked === b.locked\n ))\n )\n}\n\n/**\n * Mount sidebar\n *\n * This function doesn't set the height of the actual sidebar, but of its first\n * child \u2013 the `.md-sidebar__scrollwrap` element in order to mitigiate jittery\n * sidebars when the footer is scrolled into view. At some point we switched\n * from `absolute` / `fixed` positioning to `sticky` positioning, significantly\n * reducing jitter in some browsers (respectively Firefox and Safari) when\n * scrolling from the top. However, top-aligned sticky positioning means that\n * the sidebar snaps to the bottom when the end of the container is reached.\n * This is what leads to the mentioned jitter, as the sidebar's height may be\n * updated too slowly.\n *\n * This behaviour can be mitigiated by setting the height of the sidebar to `0`\n * while preserving the padding, and the height on its first element.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @returns Sidebar component observable\n */\nexport function mountSidebar(\n el: HTMLElement, { header$, ...options }: MountOptions\n): Observable> {\n const inner = getElement(\".md-sidebar__scrollwrap\", el)\n const { y } = getElementOffset(inner)\n return defer(() => {\n const push$ = new Subject()\n push$\n .pipe(\n auditTime(0, animationFrameScheduler),\n withLatestFrom(header$)\n )\n .subscribe({\n\n /* Handle emission */\n next([{ height }, { height: offset }]) {\n inner.style.height = `${height - 2 * y}px`\n el.style.top = `${offset}px`\n },\n\n /* Handle complete */\n complete() {\n inner.style.height = \"\"\n el.style.top = \"\"\n }\n })\n\n /* Bring active item into view on initial load */\n push$\n .pipe(\n observeOn(animationFrameScheduler),\n take(1)\n )\n .subscribe(() => {\n for (const item of getElements(\".md-nav__link--active[href]\", el)) {\n const container = getElementContainer(item)\n if (typeof container !== \"undefined\") {\n const offset = item.offsetTop - container.offsetTop\n const { height } = getElementSize(container)\n container.scrollTo({\n top: offset - height / 2\n })\n }\n }\n })\n\n /* Create and return component */\n return watchSidebar(el, options)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Repo, User } from \"github-types\"\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map,\n zip\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * GitHub release (partial)\n */\ninterface Release {\n tag_name: string /* Tag name */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub repository facts\n *\n * @param user - GitHub user or organization\n * @param repo - GitHub repository\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable {\n if (typeof repo !== \"undefined\") {\n const url = `https://api.github.com/repos/${user}/${repo}`\n return zip(\n\n /* Fetch version */\n requestJSON(`${url}/releases/latest`)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(release => ({\n version: release.tag_name\n })),\n defaultIfEmpty({})\n ),\n\n /* Fetch stars and forks */\n requestJSON(url)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(info => ({\n stars: info.stargazers_count,\n forks: info.forks_count\n })),\n defaultIfEmpty({})\n )\n )\n .pipe(\n map(([release, info]) => ({ ...release, ...info }))\n )\n\n /* User or organization */\n } else {\n const url = `https://api.github.com/users/${user}`\n return requestJSON(url)\n .pipe(\n map(info => ({\n repositories: info.public_repos\n })),\n defaultIfEmpty({})\n )\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ProjectSchema } from \"gitlab\"\nimport {\n EMPTY,\n Observable,\n catchError,\n defaultIfEmpty,\n map\n} from \"rxjs\"\n\nimport { requestJSON } from \"~/browser\"\n\nimport { SourceFacts } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitLab repository facts\n *\n * @param base - GitLab base\n * @param project - GitLab project\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFactsFromGitLab(\n base: string, project: string\n): Observable {\n const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}`\n return requestJSON(url)\n .pipe(\n catchError(() => EMPTY), // @todo refactor instant loading\n map(({ star_count, forks_count }) => ({\n stars: star_count,\n forks: forks_count\n })),\n defaultIfEmpty({})\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable } from \"rxjs\"\n\nimport { fetchSourceFactsFromGitHub } from \"../github\"\nimport { fetchSourceFactsFromGitLab } from \"../gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository facts for repositories\n */\nexport interface RepositoryFacts {\n stars?: number /* Number of stars */\n forks?: number /* Number of forks */\n version?: string /* Latest version */\n}\n\n/**\n * Repository facts for organizations\n */\nexport interface OrganizationFacts {\n repositories?: number /* Number of repositories */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Repository facts\n */\nexport type SourceFacts =\n | RepositoryFacts\n | OrganizationFacts\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch repository facts\n *\n * @param url - Repository URL\n *\n * @returns Repository facts observable\n */\nexport function fetchSourceFacts(\n url: string\n): Observable {\n\n /* Try to match GitHub repository */\n let match = url.match(/^.+github\\.com\\/([^/]+)\\/?([^/]+)?/i)\n if (match) {\n const [, user, repo] = match\n return fetchSourceFactsFromGitHub(user, repo)\n }\n\n /* Try to match GitLab repository */\n match = url.match(/^.+?([^/]*gitlab[^/]+)\\/(.+?)\\/?$/i)\n if (match) {\n const [, base, slug] = match\n return fetchSourceFactsFromGitLab(base, slug)\n }\n\n /* Fallback */\n return EMPTY\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n EMPTY,\n Observable,\n Subject,\n catchError,\n defer,\n filter,\n finalize,\n map,\n of,\n shareReplay,\n tap\n} from \"rxjs\"\n\nimport { getElement } from \"~/browser\"\nimport { ConsentDefaults } from \"~/components/consent\"\nimport { renderSourceFacts } from \"~/templates\"\n\nimport {\n Component,\n getComponentElements\n} from \"../../_\"\nimport {\n SourceFacts,\n fetchSourceFacts\n} from \"../facts\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information\n */\nexport interface Source {\n facts: SourceFacts /* Repository facts */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Repository information observable\n */\nlet fetch$: Observable\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch repository information\n *\n * This function tries to read the repository facts from session storage, and\n * if unsuccessful, fetches them from the underlying provider.\n *\n * @param el - Repository information element\n *\n * @returns Repository information observable\n */\nexport function watchSource(\n el: HTMLAnchorElement\n): Observable {\n return fetch$ ||= defer(() => {\n const cached = __md_get(\"__source\", sessionStorage)\n if (cached) {\n return of(cached)\n } else {\n\n /* Check if consent is configured and was given */\n const els = getComponentElements(\"consent\")\n if (els.length) {\n const consent = __md_get(\"__consent\")\n if (!(consent && consent.github))\n return EMPTY\n }\n\n /* Fetch repository facts */\n return fetchSourceFacts(el.href)\n .pipe(\n tap(facts => __md_set(\"__source\", facts, sessionStorage))\n )\n }\n })\n .pipe(\n catchError(() => EMPTY),\n filter(facts => Object.keys(facts).length > 0),\n map(facts => ({ facts })),\n shareReplay(1)\n )\n}\n\n/**\n * Mount repository information\n *\n * @param el - Repository information element\n *\n * @returns Repository information component observable\n */\nexport function mountSource(\n el: HTMLAnchorElement\n): Observable> {\n const inner = getElement(\":scope > :last-child\", el)\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe(({ facts }) => {\n inner.appendChild(renderSourceFacts(facts))\n inner.classList.add(\"md-source__repository--active\")\n })\n\n /* Create and return component */\n return watchSource(el)\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n defer,\n distinctUntilKeyChanged,\n finalize,\n map,\n of,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n watchElementSize,\n watchViewportAt\n} from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Navigation tabs\n */\nexport interface Tabs {\n hidden: boolean /* Navigation tabs are hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch navigation tabs\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs observable\n */\nexport function watchTabs(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n return watchElementSize(document.body)\n .pipe(\n switchMap(() => watchViewportAt(el, { header$, viewport$ })),\n map(({ offset: { y } }) => {\n return {\n hidden: y >= 10\n }\n }),\n distinctUntilKeyChanged(\"hidden\")\n )\n}\n\n/**\n * Mount navigation tabs\n *\n * This function hides the navigation tabs when scrolling past the threshold\n * and makes them reappear in a nice CSS animation when scrolling back up.\n *\n * @param el - Navigation tabs element\n * @param options - Options\n *\n * @returns Navigation tabs component observable\n */\nexport function mountTabs(\n el: HTMLElement, options: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n el.hidden = hidden\n },\n\n /* Handle complete */\n complete() {\n el.hidden = false\n }\n })\n\n /* Create and return component */\n return (\n feature(\"navigation.tabs.sticky\")\n ? of({ hidden: false })\n : watchTabs(el, options)\n )\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatestWith,\n debounceTime,\n defer,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n finalize,\n map,\n merge,\n of,\n repeat,\n scan,\n share,\n skip,\n startWith,\n switchMap,\n takeLast,\n takeUntil,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { feature } from \"~/_\"\nimport {\n Viewport,\n getElement,\n getElementContainer,\n getElementSize,\n getElements,\n getLocation,\n getOptionalElement,\n watchElementSize\n} from \"~/browser\"\n\nimport {\n Component,\n getComponentElement\n} from \"../_\"\nimport { Header } from \"../header\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Table of contents\n */\nexport interface TableOfContents {\n prev: HTMLAnchorElement[][] /* Anchors (previous) */\n next: HTMLAnchorElement[][] /* Anchors (next) */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch table of contents\n *\n * This is effectively a scroll spy implementation which will account for the\n * fixed header and automatically re-calculate anchor offsets when the viewport\n * is resized. The returned observable will only emit if the table of contents\n * needs to be repainted.\n *\n * This implementation tracks an anchor element's entire path starting from its\n * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the\n * Material theme currently doesn't make use of this information, it enables\n * the styling of the entire hierarchy through customization.\n *\n * Note that the current anchor is the last item of the `prev` anchor list.\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents observable\n */\nexport function watchTableOfContents(\n el: HTMLElement, { viewport$, header$ }: WatchOptions\n): Observable {\n const table = new Map()\n\n /* Compute anchor-to-target mapping */\n const anchors = getElements(\"[href^=\\\\#]\", el)\n for (const anchor of anchors) {\n const id = decodeURIComponent(anchor.hash.substring(1))\n const target = getOptionalElement(`[id=\"${id}\"]`)\n if (typeof target !== \"undefined\")\n table.set(anchor, target)\n }\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n map(({ height }) => {\n const main = getComponentElement(\"main\")\n const grid = getElement(\":scope > :first-child\", main)\n return height + 0.8 * (\n grid.offsetTop -\n main.offsetTop\n )\n }),\n share()\n )\n\n /* Compute partition of previous and next anchors */\n const partition$ = watchElementSize(document.body)\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n\n /* Build index to map anchor paths to vertical offsets */\n switchMap(body => defer(() => {\n let path: HTMLAnchorElement[] = []\n return of([...table].reduce((index, [anchor, target]) => {\n while (path.length) {\n const last = table.get(path[path.length - 1])!\n if (last.tagName >= target.tagName) {\n path.pop()\n } else {\n break\n }\n }\n\n /* If the current anchor is hidden, continue with its parent */\n let offset = target.offsetTop\n while (!offset && target.parentElement) {\n target = target.parentElement\n offset = target.offsetTop\n }\n\n /* Map reversed anchor path to vertical offset */\n return index.set(\n [...path = [...path, anchor]].reverse(),\n offset\n )\n }, new Map()))\n })\n .pipe(\n\n /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */\n map(index => new Map([...index].sort(([, a], [, b]) => a - b))),\n combineLatestWith(adjust$),\n\n /* Re-compute partition when viewport offset changes */\n switchMap(([index, adjust]) => viewport$\n .pipe(\n scan(([prev, next], { offset: { y }, size }) => {\n const last = y + size.height >= Math.floor(body.height)\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y || last) {\n prev = [...prev, next.shift()!]\n } else {\n break\n }\n }\n\n /* Look backward */\n while (prev.length) {\n const [, offset] = prev[prev.length - 1]\n if (offset - adjust >= y && !last) {\n next = [prev.pop()!, ...next]\n } else {\n break\n }\n }\n\n /* Return partition */\n return [prev, next]\n }, [[], [...index]]),\n distinctUntilChanged((a, b) => (\n a[0] === b[0] &&\n a[1] === b[1]\n ))\n )\n )\n )\n )\n )\n\n /* Compute and return anchor list migrations */\n return partition$\n .pipe(\n map(([prev, next]) => ({\n prev: prev.map(([path]) => path),\n next: next.map(([path]) => path)\n })),\n\n /* Extract anchor list migrations */\n startWith({ prev: [], next: [] }),\n bufferCount(2, 1),\n map(([a, b]) => {\n\n /* Moving down */\n if (a.prev.length < b.prev.length) {\n return {\n prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length),\n next: []\n }\n\n /* Moving up */\n } else {\n return {\n prev: b.prev.slice(-1),\n next: b.next.slice(0, b.next.length - a.next.length)\n }\n }\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount table of contents\n *\n * @param el - Table of contents element\n * @param options - Options\n *\n * @returns Table of contents component observable\n */\nexport function mountTableOfContents(\n el: HTMLElement, { viewport$, header$, target$ }: MountOptions\n): Observable> {\n return defer(() => {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n push$.subscribe(({ prev, next }) => {\n\n /* Look forward */\n for (const [anchor] of next) {\n anchor.classList.remove(\"md-nav__link--passed\")\n anchor.classList.remove(\"md-nav__link--active\")\n }\n\n /* Look backward */\n for (const [index, [anchor]] of prev.entries()) {\n anchor.classList.add(\"md-nav__link--passed\")\n anchor.classList.toggle(\n \"md-nav__link--active\",\n index === prev.length - 1\n )\n }\n })\n\n /* Set up following, if enabled */\n if (feature(\"toc.follow\")) {\n\n /* Toggle smooth scrolling only for anchor clicks */\n const smooth$ = merge(\n viewport$.pipe(debounceTime(1), map(() => undefined)),\n viewport$.pipe(debounceTime(250), map(() => \"smooth\" as const))\n )\n\n /* Bring active anchor into view */\n push$\n .pipe(\n filter(({ prev }) => prev.length > 0),\n withLatestFrom(smooth$)\n )\n .subscribe(([{ prev }, behavior]) => {\n const [anchor] = prev[prev.length - 1]\n if (anchor.offsetHeight) {\n\n /* Retrieve overflowing container and scroll */\n const container = getElementContainer(anchor)\n if (typeof container !== \"undefined\") {\n const offset = anchor.offsetTop - container.offsetTop\n const { height } = getElementSize(container)\n container.scrollTo({\n top: offset - height / 2,\n behavior\n })\n }\n }\n })\n }\n\n /* Set up anchor tracking, if enabled */\n if (feature(\"navigation.tracking\"))\n viewport$\n .pipe(\n takeUntil(done$),\n distinctUntilKeyChanged(\"offset\"),\n debounceTime(250),\n skip(1),\n takeUntil(target$.pipe(skip(1))),\n repeat({ delay: 250 }),\n withLatestFrom(push$)\n )\n .subscribe(([, { prev }]) => {\n const url = getLocation()\n\n /* Set hash fragment to active anchor */\n const anchor = prev[prev.length - 1]\n if (anchor && anchor.length) {\n const [active] = anchor\n const { hash } = new URL(active.href)\n if (url.hash !== hash) {\n url.hash = hash\n history.replaceState({}, \"\", `${url}`)\n }\n\n /* Reset anchor when at the top */\n } else {\n url.hash = \"\"\n history.replaceState({}, \"\", `${url}`)\n }\n })\n\n /* Create and return component */\n return watchTableOfContents(el, { viewport$, header$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n Subject,\n bufferCount,\n combineLatest,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n endWith,\n finalize,\n map,\n repeat,\n skip,\n takeLast,\n takeUntil,\n tap\n} from \"rxjs\"\n\nimport { Viewport } from \"~/browser\"\n\nimport { Component } from \"../_\"\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Back-to-top button\n */\nexport interface BackToTop {\n hidden: boolean /* Back-to-top button is hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n viewport$: Observable /* Viewport observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/**\n * Mount options\n */\ninterface MountOptions {\n viewport$: Observable /* Viewport observable */\n header$: Observable
    /* Header observable */\n main$: Observable
    /* Main area observable */\n target$: Observable /* Location target observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch back-to-top\n *\n * @param _el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top observable\n */\nexport function watchBackToTop(\n _el: HTMLElement, { viewport$, main$, target$ }: WatchOptions\n): Observable {\n\n /* Compute direction */\n const direction$ = viewport$\n .pipe(\n map(({ offset: { y } }) => y),\n bufferCount(2, 1),\n map(([a, b]) => a > b && b > 0),\n distinctUntilChanged()\n )\n\n /* Compute whether main area is active */\n const active$ = main$\n .pipe(\n map(({ active }) => active)\n )\n\n /* Compute threshold for hiding */\n return combineLatest([active$, direction$])\n .pipe(\n map(([active, direction]) => !(active && direction)),\n distinctUntilChanged(),\n takeUntil(target$.pipe(skip(1))),\n endWith(true),\n repeat({ delay: 250 }),\n map(hidden => ({ hidden }))\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Mount back-to-top\n *\n * @param el - Back-to-top element\n * @param options - Options\n *\n * @returns Back-to-top component observable\n */\nexport function mountBackToTop(\n el: HTMLElement, { viewport$, header$, main$, target$ }: MountOptions\n): Observable> {\n const push$ = new Subject()\n const done$ = push$.pipe(takeLast(1))\n push$.subscribe({\n\n /* Handle emission */\n next({ hidden }) {\n el.hidden = hidden\n if (hidden) {\n el.setAttribute(\"tabindex\", \"-1\")\n el.blur()\n } else {\n el.removeAttribute(\"tabindex\")\n }\n },\n\n /* Handle complete */\n complete() {\n el.style.top = \"\"\n el.hidden = true\n el.removeAttribute(\"tabindex\")\n }\n })\n\n /* Watch header height */\n header$\n .pipe(\n takeUntil(done$),\n distinctUntilKeyChanged(\"height\")\n )\n .subscribe(({ height }) => {\n el.style.top = `${height + 16}px`\n })\n\n /* Create and return component */\n return watchBackToTop(el, { viewport$, main$, target$ })\n .pipe(\n tap(state => push$.next(state)),\n finalize(() => push$.complete()),\n map(state => ({ ref: el, ...state }))\n )\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n takeWhile,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch indeterminate checkboxes\n *\n * This function replaces the indeterminate \"pseudo state\" with the actual\n * indeterminate state, which is used to keep navigation always expanded.\n *\n * @param options - Options\n */\nexport function patchIndeterminate(\n { document$, tablet$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\n // @todo `data-md-state` is deprecated and removed in v9\n \".md-toggle--indeterminate, [data-md-state=indeterminate]\"\n )),\n tap(el => {\n el.indeterminate = true\n el.checked = false\n }),\n mergeMap(el => fromEvent(el, \"change\")\n .pipe(\n takeWhile(() => el.classList.contains(\"md-toggle--indeterminate\")),\n map(() => el)\n )\n ),\n withLatestFrom(tablet$)\n )\n .subscribe(([el, tablet]) => {\n el.classList.remove(\"md-toggle--indeterminate\")\n if (tablet)\n el.checked = false\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n filter,\n fromEvent,\n map,\n mergeMap,\n switchMap,\n tap\n} from \"rxjs\"\n\nimport { getElements } from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether the given device is an Apple device\n *\n * @returns Test result\n */\nfunction isAppleDevice(): boolean {\n return /(iPad|iPhone|iPod)/.test(navigator.userAgent)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all elements with `data-md-scrollfix` attributes\n *\n * This is a year-old patch which ensures that overflow scrolling works at the\n * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon\n * the start of a touch event.\n *\n * @see https://bit.ly/2SCtAOO - Original source\n *\n * @param options - Options\n */\nexport function patchScrollfix(\n { document$ }: PatchOptions\n): void {\n document$\n .pipe(\n switchMap(() => getElements(\"[data-md-scrollfix]\")),\n tap(el => el.removeAttribute(\"data-md-scrollfix\")),\n filter(isAppleDevice),\n mergeMap(el => fromEvent(el, \"touchstart\")\n .pipe(\n map(() => el)\n )\n )\n )\n .subscribe(el => {\n const top = el.scrollTop\n\n /* We're at the top of the container */\n if (top === 0) {\n el.scrollTop = 1\n\n /* We're at the bottom of the container */\n } else if (top + el.offsetHeight === el.scrollHeight) {\n el.scrollTop = top - 1\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n combineLatest,\n delay,\n map,\n of,\n switchMap,\n withLatestFrom\n} from \"rxjs\"\n\nimport {\n Viewport,\n watchToggle\n} from \"~/browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n viewport$: Observable /* Viewport observable */\n tablet$: Observable /* Media tablet observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch the document body to lock when search is open\n *\n * For mobile and tablet viewports, the search is rendered full screen, which\n * leads to scroll leaking when at the top or bottom of the search result. This\n * function locks the body when the search is in full screen mode, and restores\n * the scroll position when leaving.\n *\n * @param options - Options\n */\nexport function patchScrolllock(\n { viewport$, tablet$ }: PatchOptions\n): void {\n combineLatest([watchToggle(\"search\"), tablet$])\n .pipe(\n map(([active, tablet]) => active && !tablet),\n switchMap(active => of(active)\n .pipe(\n delay(active ? 400 : 100)\n )\n ),\n withLatestFrom(viewport$)\n )\n .subscribe(([active, { offset: { y }}]) => {\n if (active) {\n document.body.setAttribute(\"data-md-scrolllock\", \"\")\n document.body.style.top = `-${y}px`\n } else {\n const value = -1 * parseInt(document.body.style.top, 10)\n document.body.removeAttribute(\"data-md-scrolllock\")\n document.body.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n }\n })\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node === \"string\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n"], + "mappings": "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", + "names": ["require_focus_visible", "__commonJSMin", "exports", "module", "global", "factory", "applyFocusVisiblePolyfill", "scope", "hadKeyboardEvent", "hadFocusVisibleRecently", "hadFocusVisibleRecentlyTimeout", "inputTypesAllowlist", "isValidFocusTarget", "el", "focusTriggersKeyboardModality", "type", "tagName", "addFocusVisibleClass", "removeFocusVisibleClass", "onKeyDown", "e", "onPointerDown", "onFocus", "onBlur", "onVisibilityChange", "addInitialPointerMoveListeners", "onInitialPointerMove", "removeInitialPointerMoveListeners", "event", "error", "require_url_polyfill", "__commonJSMin", "exports", "global", "checkIfIteratorIsSupported", "error", "iteratorSupported", "createIterator", "items", "iterator", "value", "serializeParam", "deserializeParam", "polyfillURLSearchParams", "URLSearchParams", "searchString", "typeofSearchString", "_this", "name", "i", "entry", "key", "proto", "callback", "thisArg", "entries", "searchArray", "checkIfURLSearchParamsSupported", "e", "a", "b", "keys", "attributes", "attribute", "checkIfURLIsSupported", "u", "polyfillURL", "_URL", "URL", "url", "base", "doc", "baseElement", "err", "anchorElement", "inputElement", "searchParams", "enableSearchUpdate", "enableSearchParamsUpdate", "methodName", "method", "search", "linkURLWithAnchorAttribute", "attributeName", "expectedPort", "addPortToOrigin", "blob", "getOrigin", "require_tslib", "__commonJSMin", "exports", "module", "__extends", "__assign", "__rest", "__decorate", "__param", "__metadata", "__awaiter", "__generator", "__exportStar", "__values", "__read", "__spread", "__spreadArrays", "__spreadArray", "__await", "__asyncGenerator", "__asyncDelegator", "__asyncValues", "__makeTemplateObject", "__importStar", "__importDefault", "__classPrivateFieldGet", "__classPrivateFieldSet", "__createBinding", "factory", "root", "createExporter", "previous", "id", "v", "exporter", "extendStatics", "d", "b", "p", "__", "t", "s", "n", "e", "i", "decorators", "target", "key", "desc", "c", "r", "paramIndex", "decorator", "metadataKey", "metadataValue", "thisArg", "_arguments", "P", "generator", "adopt", "value", "resolve", "reject", "fulfilled", "step", "rejected", "result", "body", "_", "f", "y", "g", "verb", "op", "m", "o", "k", "k2", "ar", "error", "il", "a", "j", "jl", "to", "from", "pack", "l", "q", "resume", "settle", "fulfill", "cooked", "raw", "__setModuleDefault", "mod", "receiver", "state", "kind", "require_clipboard", "__commonJSMin", "exports", "module", "root", "factory", "__webpack_modules__", "__unused_webpack_module", "__webpack_exports__", "__webpack_require__", "clipboard", "tiny_emitter", "tiny_emitter_default", "listen", "listen_default", "src_select", "select_default", "command", "type", "err", "ClipboardActionCut", "target", "selectedText", "actions_cut", "createFakeElement", "value", "isRTL", "fakeElement", "yPosition", "fakeCopyAction", "options", "ClipboardActionCopy", "actions_copy", "_typeof", "obj", "ClipboardActionDefault", "_options$action", "action", "container", "text", "actions_default", "clipboard_typeof", "_classCallCheck", "instance", "Constructor", "_defineProperties", "props", "i", "descriptor", "_createClass", "protoProps", "staticProps", "_inherits", "subClass", "superClass", "_setPrototypeOf", "o", "p", "_createSuper", "Derived", "hasNativeReflectConstruct", "_isNativeReflectConstruct", "Super", "_getPrototypeOf", "result", "NewTarget", "_possibleConstructorReturn", "self", "call", "_assertThisInitialized", "e", "getAttributeValue", "suffix", "element", "attribute", "Clipboard", "_Emitter", "_super", "trigger", "_this", "_this2", "selector", "actions", "support", "DOCUMENT_NODE_TYPE", "proto", "closest", "__unused_webpack_exports", "_delegate", "callback", "useCapture", "listenerFn", "listener", "delegate", "elements", "is", "listenNode", "listenNodeList", "listenSelector", "node", "nodeList", "select", "isReadOnly", "selection", "range", "E", "name", "ctx", "data", "evtArr", "len", "evts", "liveEvents", "__webpack_module_cache__", "moduleId", "getter", "definition", "key", "prop", "require_escape_html", "__commonJSMin", "exports", "module", "matchHtmlRegExp", "escapeHtml", "string", "str", "match", "escape", "html", "index", "lastIndex", "r", "a", "e", "import_focus_visible", "n", "t", "s", "r", "o", "u", "i", "a", "e", "c", "import_url_polyfill", "import_tslib", "__extends", "__assign", "__rest", "__decorate", "__param", "__metadata", "__awaiter", "__generator", "__exportStar", "__createBinding", "__values", "__read", "__spread", "__spreadArrays", "__spreadArray", "__await", "__asyncGenerator", "__asyncDelegator", "__asyncValues", "__makeTemplateObject", "__importStar", "__importDefault", "__classPrivateFieldGet", "__classPrivateFieldSet", "tslib", "isFunction", "value", "createErrorClass", "createImpl", "_super", "instance", "ctorFunc", "UnsubscriptionError", "createErrorClass", "_super", "errors", "err", "i", "arrRemove", "arr", "item", "index", "Subscription", "initialTeardown", "errors", "_parentage", "_parentage_1", "__values", "_parentage_1_1", "parent_1", "initialFinalizer", "isFunction", "e", "UnsubscriptionError", "_finalizers", "_finalizers_1", "_finalizers_1_1", "finalizer", "execFinalizer", "err", "__spreadArray", "__read", "teardown", "_a", "parent", "arrRemove", "empty", "EMPTY_SUBSCRIPTION", "Subscription", "isSubscription", "value", "isFunction", "execFinalizer", "finalizer", "config", "timeoutProvider", "handler", "timeout", "args", "_i", "delegate", "__spreadArray", "__read", "handle", "reportUnhandledError", "err", "timeoutProvider", "onUnhandledError", "config", "noop", "COMPLETE_NOTIFICATION", "createNotification", "errorNotification", "error", "nextNotification", "value", "kind", "context", "errorContext", "cb", "config", "isRoot", "_a", "errorThrown", "error", "captureError", "err", "Subscriber", "_super", "__extends", "destination", "_this", "isSubscription", "EMPTY_OBSERVER", "next", "error", "complete", "SafeSubscriber", "value", "handleStoppedNotification", "nextNotification", "err", "errorNotification", "COMPLETE_NOTIFICATION", "Subscription", "_bind", "bind", "fn", "thisArg", "ConsumerObserver", "partialObserver", "value", "error", "handleUnhandledError", "err", "SafeSubscriber", "_super", "__extends", "observerOrNext", "complete", "_this", "isFunction", "context_1", "config", "Subscriber", "handleUnhandledError", "error", "config", "captureError", "reportUnhandledError", "defaultErrorHandler", "err", "handleStoppedNotification", "notification", "subscriber", "onStoppedNotification", "timeoutProvider", "EMPTY_OBSERVER", "noop", "observable", "identity", "x", "pipe", "fns", "_i", "pipeFromArray", "identity", "input", "prev", "fn", "Observable", "subscribe", "operator", "observable", "observerOrNext", "error", "complete", "_this", "subscriber", "isSubscriber", "SafeSubscriber", "errorContext", "_a", "source", "sink", "err", "next", "promiseCtor", "getPromiseCtor", "resolve", "reject", "value", "operations", "_i", "pipeFromArray", "x", "getPromiseCtor", "promiseCtor", "_a", "config", "isObserver", "value", "isFunction", "isSubscriber", "Subscriber", "isSubscription", "hasLift", "source", "isFunction", "operate", "init", "liftedSource", "err", "createOperatorSubscriber", "destination", "onNext", "onComplete", "onError", "onFinalize", "OperatorSubscriber", "_super", "__extends", "shouldUnsubscribe", "_this", "value", "err", "closed_1", "_a", "Subscriber", "animationFrameProvider", "callback", "request", "cancel", "delegate", "handle", "timestamp", "Subscription", "args", "_i", "__spreadArray", "__read", "ObjectUnsubscribedError", "createErrorClass", "_super", "Subject", "_super", "__extends", "_this", "operator", "subject", "AnonymousSubject", "ObjectUnsubscribedError", "value", "errorContext", "_b", "__values", "_c", "observer", "err", "observers", "_a", "subscriber", "hasError", "isStopped", "EMPTY_SUBSCRIPTION", "Subscription", "arrRemove", "thrownError", "observable", "Observable", "destination", "source", "AnonymousSubject", "_super", "__extends", "destination", "source", "_this", "value", "_b", "_a", "err", "subscriber", "EMPTY_SUBSCRIPTION", "Subject", "dateTimestampProvider", "ReplaySubject", "_super", "__extends", "_bufferSize", "_windowTime", "_timestampProvider", "dateTimestampProvider", "_this", "value", "_a", "isStopped", "_buffer", "_infiniteTimeWindow", "subscriber", "subscription", "copy", "i", "adjustedBufferSize", "now", "last", "Subject", "Action", "_super", "__extends", "scheduler", "work", "state", "delay", "Subscription", "intervalProvider", "handler", "timeout", "args", "_i", "delegate", "__spreadArray", "__read", "handle", "AsyncAction", "_super", "__extends", "scheduler", "work", "_this", "state", "delay", "id", "_a", "_id", "intervalProvider", "_scheduler", "error", "_delay", "errored", "errorValue", "e", "actions", "arrRemove", "Action", "Scheduler", "schedulerActionCtor", "now", "work", "delay", "state", "dateTimestampProvider", "AsyncScheduler", "_super", "__extends", "SchedulerAction", "now", "Scheduler", "_this", "action", "actions", "error", "asyncScheduler", "AsyncScheduler", "AsyncAction", "async", "AnimationFrameAction", "_super", "__extends", "scheduler", "work", "_this", "id", "delay", "animationFrameProvider", "actions", "_a", "AsyncAction", "AnimationFrameScheduler", "_super", "__extends", "action", "flushId", "actions", "error", "AsyncScheduler", "animationFrameScheduler", "AnimationFrameScheduler", "AnimationFrameAction", "EMPTY", "Observable", "subscriber", "isScheduler", "value", "isFunction", "last", "arr", "popResultSelector", "args", "isFunction", "popScheduler", "isScheduler", "popNumber", "defaultValue", "isArrayLike", "x", "isPromise", "value", "isFunction", "isInteropObservable", "input", "isFunction", "observable", "isAsyncIterable", "obj", "isFunction", "createInvalidObservableTypeError", "input", "getSymbolIterator", "iterator", "isIterable", "input", "isFunction", "iterator", "readableStreamLikeToAsyncGenerator", "readableStream", "reader", "__await", "_a", "_b", "value", "done", "isReadableStreamLike", "obj", "isFunction", "innerFrom", "input", "Observable", "isInteropObservable", "fromInteropObservable", "isArrayLike", "fromArrayLike", "isPromise", "fromPromise", "isAsyncIterable", "fromAsyncIterable", "isIterable", "fromIterable", "isReadableStreamLike", "fromReadableStreamLike", "createInvalidObservableTypeError", "obj", "subscriber", "obs", "observable", "isFunction", "array", "i", "promise", "value", "err", "reportUnhandledError", "iterable", "iterable_1", "__values", "iterable_1_1", "asyncIterable", "process", "readableStream", "readableStreamLikeToAsyncGenerator", "asyncIterable_1", "__asyncValues", "asyncIterable_1_1", "executeSchedule", "parentSubscription", "scheduler", "work", "delay", "repeat", "scheduleSubscription", "observeOn", "scheduler", "delay", "operate", "source", "subscriber", "createOperatorSubscriber", "value", "executeSchedule", "err", "subscribeOn", "scheduler", "delay", "operate", "source", "subscriber", "scheduleObservable", "input", "scheduler", "innerFrom", "subscribeOn", "observeOn", "schedulePromise", "input", "scheduler", "innerFrom", "subscribeOn", "observeOn", "scheduleArray", "input", "scheduler", "Observable", "subscriber", "i", "scheduleIterable", "input", "scheduler", "Observable", "subscriber", "iterator", "executeSchedule", "value", "done", "_a", "err", "isFunction", "scheduleAsyncIterable", "input", "scheduler", "Observable", "subscriber", "executeSchedule", "iterator", "result", "scheduleReadableStreamLike", "input", "scheduler", "scheduleAsyncIterable", "readableStreamLikeToAsyncGenerator", "scheduled", "input", "scheduler", "isInteropObservable", "scheduleObservable", "isArrayLike", "scheduleArray", "isPromise", "schedulePromise", "isAsyncIterable", "scheduleAsyncIterable", "isIterable", "scheduleIterable", "isReadableStreamLike", "scheduleReadableStreamLike", "createInvalidObservableTypeError", "from", "input", "scheduler", "scheduled", "innerFrom", "of", "args", "_i", "scheduler", "popScheduler", "from", "throwError", "errorOrErrorFactory", "scheduler", "errorFactory", "isFunction", "init", "subscriber", "Observable", "isValidDate", "value", "map", "project", "thisArg", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "isArray", "callOrApply", "fn", "args", "__spreadArray", "__read", "mapOneOrManyArgs", "map", "isArray", "getPrototypeOf", "objectProto", "getKeys", "argsArgArrayOrObject", "args", "first_1", "isPOJO", "keys", "key", "obj", "createObject", "keys", "values", "result", "key", "i", "combineLatest", "args", "_i", "scheduler", "popScheduler", "resultSelector", "popResultSelector", "_a", "argsArgArrayOrObject", "observables", "keys", "from", "result", "Observable", "combineLatestInit", "values", "createObject", "identity", "mapOneOrManyArgs", "valueTransform", "subscriber", "maybeSchedule", "length", "active", "remainingFirstValues", "i", "source", "hasFirstValue", "createOperatorSubscriber", "value", "execute", "subscription", "executeSchedule", "mergeInternals", "source", "subscriber", "project", "concurrent", "onBeforeNext", "expand", "innerSubScheduler", "additionalFinalizer", "buffer", "active", "index", "isComplete", "checkComplete", "outerNext", "value", "doInnerSub", "innerComplete", "innerFrom", "createOperatorSubscriber", "innerValue", "bufferedValue", "executeSchedule", "err", "mergeMap", "project", "resultSelector", "concurrent", "isFunction", "a", "i", "map", "b", "ii", "innerFrom", "operate", "source", "subscriber", "mergeInternals", "mergeAll", "concurrent", "mergeMap", "identity", "concatAll", "mergeAll", "concat", "args", "_i", "concatAll", "from", "popScheduler", "defer", "observableFactory", "Observable", "subscriber", "innerFrom", "nodeEventEmitterMethods", "eventTargetMethods", "jqueryMethods", "fromEvent", "target", "eventName", "options", "resultSelector", "isFunction", "mapOneOrManyArgs", "_a", "__read", "isEventTarget", "methodName", "handler", "isNodeStyleEventEmitter", "toCommonHandlerRegistry", "isJQueryStyleEventEmitter", "add", "remove", "isArrayLike", "mergeMap", "subTarget", "innerFrom", "Observable", "subscriber", "args", "_i", "fromEventPattern", "addHandler", "removeHandler", "resultSelector", "mapOneOrManyArgs", "Observable", "subscriber", "handler", "e", "_i", "retValue", "isFunction", "timer", "dueTime", "intervalOrScheduler", "scheduler", "async", "intervalDuration", "isScheduler", "Observable", "subscriber", "due", "isValidDate", "n", "merge", "args", "_i", "scheduler", "popScheduler", "concurrent", "popNumber", "sources", "innerFrom", "mergeAll", "from", "EMPTY", "NEVER", "Observable", "noop", "isArray", "argsOrArgArray", "args", "filter", "predicate", "thisArg", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "zip", "args", "_i", "resultSelector", "popResultSelector", "sources", "argsOrArgArray", "Observable", "subscriber", "buffers", "completed", "sourceIndex", "innerFrom", "createOperatorSubscriber", "value", "buffer", "result", "__spreadArray", "__read", "i", "EMPTY", "audit", "durationSelector", "operate", "source", "subscriber", "hasValue", "lastValue", "durationSubscriber", "isComplete", "endDuration", "value", "cleanupDuration", "createOperatorSubscriber", "innerFrom", "auditTime", "duration", "scheduler", "asyncScheduler", "audit", "timer", "bufferCount", "bufferSize", "startBufferEvery", "operate", "source", "subscriber", "buffers", "count", "createOperatorSubscriber", "value", "toEmit", "buffers_1", "__values", "buffers_1_1", "buffer", "toEmit_1", "toEmit_1_1", "arrRemove", "buffers_2", "buffers_2_1", "catchError", "selector", "operate", "source", "subscriber", "innerSub", "syncUnsub", "handledResult", "createOperatorSubscriber", "err", "innerFrom", "scanInternals", "accumulator", "seed", "hasSeed", "emitOnNext", "emitBeforeComplete", "source", "subscriber", "hasState", "state", "index", "createOperatorSubscriber", "value", "i", "combineLatest", "args", "_i", "resultSelector", "popResultSelector", "pipe", "__spreadArray", "__read", "mapOneOrManyArgs", "operate", "source", "subscriber", "combineLatestInit", "argsOrArgArray", "combineLatestWith", "otherSources", "_i", "combineLatest", "__spreadArray", "__read", "concatMap", "project", "resultSelector", "isFunction", "mergeMap", "debounceTime", "dueTime", "scheduler", "asyncScheduler", "operate", "source", "subscriber", "activeTask", "lastValue", "lastTime", "emit", "value", "emitWhenIdle", "targetTime", "now", "createOperatorSubscriber", "defaultIfEmpty", "defaultValue", "operate", "source", "subscriber", "hasValue", "createOperatorSubscriber", "value", "take", "count", "EMPTY", "operate", "source", "subscriber", "seen", "createOperatorSubscriber", "value", "ignoreElements", "operate", "source", "subscriber", "createOperatorSubscriber", "noop", "mapTo", "value", "map", "delayWhen", "delayDurationSelector", "subscriptionDelay", "source", "concat", "take", "ignoreElements", "mergeMap", "value", "index", "mapTo", "delay", "due", "scheduler", "asyncScheduler", "duration", "timer", "delayWhen", "distinctUntilChanged", "comparator", "keySelector", "identity", "defaultCompare", "operate", "source", "subscriber", "previousKey", "first", "createOperatorSubscriber", "value", "currentKey", "a", "b", "distinctUntilKeyChanged", "key", "compare", "distinctUntilChanged", "x", "y", "endWith", "values", "_i", "source", "concat", "of", "__spreadArray", "__read", "finalize", "callback", "operate", "source", "subscriber", "takeLast", "count", "EMPTY", "operate", "source", "subscriber", "buffer", "createOperatorSubscriber", "value", "buffer_1", "__values", "buffer_1_1", "merge", "args", "_i", "scheduler", "popScheduler", "concurrent", "popNumber", "argsOrArgArray", "operate", "source", "subscriber", "mergeAll", "from", "__spreadArray", "__read", "mergeWith", "otherSources", "_i", "merge", "__spreadArray", "__read", "repeat", "countOrConfig", "count", "delay", "_a", "EMPTY", "operate", "source", "subscriber", "soFar", "sourceSub", "resubscribe", "notifier", "timer", "innerFrom", "notifierSubscriber_1", "createOperatorSubscriber", "subscribeToSource", "syncUnsub", "sample", "notifier", "operate", "source", "subscriber", "hasValue", "lastValue", "createOperatorSubscriber", "value", "noop", "scan", "accumulator", "seed", "operate", "scanInternals", "share", "options", "_a", "connector", "Subject", "_b", "resetOnError", "_c", "resetOnComplete", "_d", "resetOnRefCountZero", "wrapperSource", "connection", "resetConnection", "subject", "refCount", "hasCompleted", "hasErrored", "cancelReset", "reset", "resetAndUnsubscribe", "conn", "operate", "source", "subscriber", "dest", "handleReset", "SafeSubscriber", "value", "err", "innerFrom", "on", "args", "_i", "onSubscriber", "__spreadArray", "__read", "shareReplay", "configOrBufferSize", "windowTime", "scheduler", "bufferSize", "refCount", "_a", "_b", "_c", "share", "ReplaySubject", "skip", "count", "filter", "_", "index", "skipUntil", "notifier", "operate", "source", "subscriber", "taking", "skipSubscriber", "createOperatorSubscriber", "noop", "innerFrom", "value", "startWith", "values", "_i", "scheduler", "popScheduler", "operate", "source", "subscriber", "concat", "switchMap", "project", "resultSelector", "operate", "source", "subscriber", "innerSubscriber", "index", "isComplete", "checkComplete", "createOperatorSubscriber", "value", "innerIndex", "outerIndex", "innerFrom", "innerValue", "takeUntil", "notifier", "operate", "source", "subscriber", "innerFrom", "createOperatorSubscriber", "noop", "takeWhile", "predicate", "inclusive", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "result", "tap", "observerOrNext", "error", "complete", "tapObserver", "isFunction", "operate", "source", "subscriber", "_a", "isUnsub", "createOperatorSubscriber", "value", "err", "_b", "identity", "defaultThrottleConfig", "throttle", "durationSelector", "config", "operate", "source", "subscriber", "leading", "trailing", "hasValue", "sendValue", "throttled", "isComplete", "endThrottling", "send", "cleanupThrottling", "startThrottle", "value", "innerFrom", "createOperatorSubscriber", "throttleTime", "duration", "scheduler", "config", "asyncScheduler", "defaultThrottleConfig", "duration$", "timer", "throttle", "withLatestFrom", "inputs", "_i", "project", "popResultSelector", "operate", "source", "subscriber", "len", "otherValues", "hasValue", "ready", "i", "innerFrom", "createOperatorSubscriber", "value", "identity", "noop", "values", "__spreadArray", "__read", "zip", "sources", "_i", "operate", "source", "subscriber", "__spreadArray", "__read", "zipWith", "otherInputs", "_i", "zip", "__spreadArray", "__read", "watchDocument", "document$", "ReplaySubject", "fromEvent", "getElements", "selector", "node", "getElement", "el", "getOptionalElement", "getActiveElement", "watchElementFocus", "el", "merge", "fromEvent", "debounceTime", "map", "active", "getActiveElement", "startWith", "distinctUntilChanged", "getElementOffset", "el", "watchElementOffset", "merge", "fromEvent", "auditTime", "animationFrameScheduler", "map", "startWith", "getElementContentOffset", "el", "watchElementContentOffset", "merge", "fromEvent", "auditTime", "animationFrameScheduler", "map", "startWith", "MapShim", "getIndex", "arr", "key", "result", "entry", "index", "class_1", "value", "entries", "callback", "ctx", "_i", "_a", "isBrowser", "global$1", "requestAnimationFrame$1", "trailingTimeout", "throttle", "delay", "leadingCall", "trailingCall", "lastCallTime", "resolvePending", "proxy", "timeoutCallback", "timeStamp", "REFRESH_DELAY", "transitionKeys", "mutationObserverSupported", "ResizeObserverController", "observer", "observers", "changesDetected", "activeObservers", "_b", "propertyName", "isReflowProperty", "defineConfigurable", "target", "props", "getWindowOf", "ownerGlobal", "emptyRect", "createRectInit", "toFloat", "getBordersSize", "styles", "positions", "size", "position", "getPaddings", "paddings", "positions_1", "getSVGContentRect", "bbox", "getHTMLElementContentRect", "clientWidth", "clientHeight", "horizPad", "vertPad", "width", "height", "isDocumentElement", "vertScrollbar", "horizScrollbar", "isSVGGraphicsElement", "getContentRect", "createReadOnlyRect", "x", "y", "Constr", "rect", "ResizeObservation", "ResizeObserverEntry", "rectInit", "contentRect", "ResizeObserverSPI", "controller", "callbackCtx", "observations", "_this", "observation", "ResizeObserver", "method", "ResizeObserver_es_default", "entry$", "Subject", "observer$", "defer", "of", "ResizeObserver_es_default", "entries", "entry", "switchMap", "observer", "merge", "NEVER", "finalize", "shareReplay", "getElementSize", "el", "watchElementSize", "tap", "filter", "target", "map", "startWith", "getElementContentSize", "el", "getElementContainer", "parent", "entry$", "Subject", "observer$", "defer", "of", "entries", "entry", "switchMap", "observer", "merge", "NEVER", "finalize", "shareReplay", "watchElementVisibility", "el", "tap", "filter", "target", "map", "isIntersecting", "watchElementBoundary", "threshold", "watchElementContentOffset", "y", "visible", "getElementSize", "content", "getElementContentSize", "distinctUntilChanged", "toggles", "getElement", "getToggle", "name", "setToggle", "value", "watchToggle", "el", "fromEvent", "map", "startWith", "isSusceptibleToKeyboard", "el", "type", "watchKeyboard", "fromEvent", "filter", "ev", "map", "getToggle", "mode", "active", "getActiveElement", "share", "getLocation", "setLocation", "url", "watchLocation", "Subject", "appendChild", "el", "child", "node", "h", "tag", "attributes", "children", "attr", "truncate", "value", "n", "i", "round", "digits", "getLocationHash", "setLocationHash", "hash", "el", "h", "ev", "watchLocationHash", "fromEvent", "map", "startWith", "filter", "shareReplay", "watchLocationTarget", "id", "getOptionalElement", "watchMedia", "query", "media", "fromEventPattern", "next", "startWith", "watchPrint", "merge", "fromEvent", "map", "at", "query$", "factory", "switchMap", "active", "EMPTY", "request", "url", "options", "from", "catchError", "EMPTY", "switchMap", "res", "throwError", "of", "requestJSON", "shareReplay", "requestXML", "dom", "map", "watchScript", "src", "script", "h", "defer", "merge", "fromEvent", "switchMap", "throwError", "map", "finalize", "take", "getViewportOffset", "watchViewportOffset", "merge", "fromEvent", "map", "startWith", "getViewportSize", "watchViewportSize", "fromEvent", "map", "startWith", "watchViewport", "combineLatest", "watchViewportOffset", "watchViewportSize", "map", "offset", "size", "shareReplay", "watchViewportAt", "el", "viewport$", "header$", "size$", "distinctUntilKeyChanged", "offset$", "combineLatest", "map", "getElementOffset", "height", "offset", "size", "x", "y", "watchWorker", "worker", "tx$", "rx$", "fromEvent", "map", "data", "throttle", "tap", "message", "switchMap", "share", "script", "getElement", "config", "getLocation", "configuration", "feature", "flag", "translation", "key", "value", "getComponentElement", "type", "node", "getElement", "getComponentElements", "getElements", "watchAnnounce", "el", "button", "getElement", "fromEvent", "map", "content", "mountAnnounce", "feature", "EMPTY", "defer", "push$", "Subject", "startWith", "hash", "_a", "tap", "state", "finalize", "__spreadValues", "watchConsent", "el", "target$", "map", "target", "mountConsent", "options", "internal$", "Subject", "hidden", "tap", "state", "finalize", "__spreadValues", "import_clipboard", "renderTooltip", "id", "h", "renderAnnotation", "id", "prefix", "anchor", "h", "renderTooltip", "renderClipboardButton", "id", "h", "translation", "renderSearchDocument", "document", "flag", "parent", "teaser", "missing", "key", "list", "h", "url", "feature", "match", "highlight", "value", "tags", "configuration", "truncate", "tag", "id", "type", "translation", "renderSearchResultItem", "result", "threshold", "docs", "doc", "article", "index", "best", "more", "children", "section", "renderSourceFacts", "facts", "h", "key", "value", "round", "renderTabbedControl", "type", "classes", "h", "renderTable", "table", "h", "renderVersion", "version", "config", "configuration", "url", "h", "renderVersionSelector", "versions", "active", "translation", "watchAnnotation", "el", "container", "offset$", "defer", "combineLatest", "watchElementOffset", "watchElementContentOffset", "map", "x", "y", "scroll", "width", "height", "getElementSize", "watchElementFocus", "switchMap", "active", "offset", "take", "mountAnnotation", "target$", "tooltip", "index", "push$", "Subject", "done$", "takeLast", "watchElementVisibility", "takeUntil", "visible", "merge", "filter", "debounceTime", "auditTime", "animationFrameScheduler", "throttleTime", "origin", "fromEvent", "ev", "withLatestFrom", "_a", "parent", "getActiveElement", "target", "delay", "tap", "state", "finalize", "__spreadValues", "findAnnotationMarkers", "container", "markers", "el", "getElements", "nodes", "it", "node", "text", "match", "id", "force", "marker", "swap", "source", "target", "mountAnnotationList", "target$", "print$", "parent", "prefix", "annotations", "getOptionalElement", "renderAnnotation", "EMPTY", "defer", "done$", "Subject", "pairs", "annotation", "getElement", "takeUntil", "takeLast", "active", "inner", "child", "merge", "mountAnnotation", "finalize", "share", "sequence", "findCandidateList", "el", "sibling", "watchCodeBlock", "watchElementSize", "map", "width", "getElementContentSize", "distinctUntilKeyChanged", "mountCodeBlock", "options", "hover", "factory$", "defer", "push$", "Subject", "scrollable", "ClipboardJS", "parent", "renderClipboardButton", "container", "list", "feature", "annotations$", "mountAnnotationList", "tap", "state", "finalize", "__spreadValues", "mergeWith", "height", "distinctUntilChanged", "switchMap", "active", "EMPTY", "watchElementVisibility", "filter", "visible", "take", "mermaid$", "sequence", "fetchScripts", "watchScript", "of", "mountMermaid", "el", "tap", "mermaid_default", "map", "shareReplay", "id", "host", "h", "svg", "shadow", "watchDetails", "el", "target$", "print$", "open", "merge", "map", "target", "filter", "details", "active", "tap", "mountDetails", "options", "defer", "push$", "Subject", "action", "reveal", "state", "finalize", "__spreadValues", "sentinel", "h", "mountDataTable", "el", "renderTable", "of", "watchContentTabs", "el", "inputs", "getElements", "initial", "input", "merge", "fromEvent", "map", "getElement", "startWith", "active", "mountContentTabs", "viewport$", "prev", "renderTabbedControl", "next", "container", "defer", "push$", "Subject", "done$", "takeLast", "combineLatest", "watchElementSize", "auditTime", "animationFrameScheduler", "takeUntil", "size", "offset", "getElementOffset", "width", "getElementSize", "content", "getElementContentOffset", "watchElementContentOffset", "getElementContentSize", "direction", "feature", "skip", "withLatestFrom", "tab", "y", "set", "label", "tabs", "tap", "state", "finalize", "__spreadValues", "subscribeOn", "asyncScheduler", "mountContent", "el", "viewport$", "target$", "print$", "merge", "getElements", "child", "mountCodeBlock", "mountMermaid", "mountDataTable", "mountDetails", "mountContentTabs", "watchDialog", "_el", "alert$", "switchMap", "message", "merge", "of", "delay", "map", "active", "mountDialog", "el", "options", "inner", "getElement", "defer", "push$", "Subject", "tap", "state", "finalize", "__spreadValues", "isHidden", "viewport$", "feature", "of", "direction$", "map", "y", "bufferCount", "a", "b", "distinctUntilKeyChanged", "hidden$", "combineLatest", "filter", "offset", "direction", "distinctUntilChanged", "search$", "watchToggle", "search", "switchMap", "active", "startWith", "watchHeader", "el", "options", "defer", "watchElementSize", "height", "hidden", "shareReplay", "mountHeader", "header$", "main$", "push$", "Subject", "done$", "takeLast", "combineLatestWith", "takeUntil", "state", "__spreadValues", "watchHeaderTitle", "el", "viewport$", "header$", "watchViewportAt", "map", "y", "height", "getElementSize", "distinctUntilKeyChanged", "mountHeaderTitle", "options", "defer", "push$", "Subject", "active", "heading", "getOptionalElement", "EMPTY", "tap", "state", "finalize", "__spreadValues", "watchMain", "el", "viewport$", "header$", "adjust$", "map", "height", "distinctUntilChanged", "border$", "switchMap", "watchElementSize", "distinctUntilKeyChanged", "combineLatest", "header", "top", "bottom", "y", "a", "b", "watchPalette", "inputs", "current", "input", "of", "mergeMap", "fromEvent", "map", "startWith", "shareReplay", "mountPalette", "el", "defer", "push$", "Subject", "palette", "key", "value", "index", "label", "observeOn", "asyncScheduler", "getElements", "tap", "state", "finalize", "__spreadValues", "import_clipboard", "extract", "el", "text", "setupClipboardJS", "alert$", "ClipboardJS", "Observable", "subscriber", "getElement", "ev", "tap", "map", "translation", "preprocess", "urls", "root", "next", "a", "b", "url", "index", "fetchSitemap", "base", "cached", "of", "config", "configuration", "requestXML", "map", "sitemap", "getElements", "node", "catchError", "EMPTY", "defaultIfEmpty", "tap", "setupInstantLoading", "document$", "location$", "viewport$", "config", "configuration", "fromEvent", "favicon", "getOptionalElement", "push$", "fetchSitemap", "map", "paths", "path", "switchMap", "urls", "filter", "ev", "el", "url", "of", "NEVER", "share", "pop$", "merge", "distinctUntilChanged", "a", "b", "response$", "distinctUntilKeyChanged", "request", "catchError", "setLocation", "sample", "dom", "res", "skip", "replacement", "selector", "feature", "source", "target", "getComponentElement", "getElements", "concatMap", "script", "h", "name", "Observable", "observer", "EMPTY", "offset", "setLocationHash", "skipUntil", "debounceTime", "bufferCount", "state", "import_escape_html", "import_escape_html", "setupSearchHighlighter", "config", "escape", "separator", "highlight", "_", "data", "term", "query", "match", "value", "escapeHTML", "defaultTransform", "query", "terms", "index", "isSearchReadyMessage", "message", "isSearchQueryMessage", "isSearchResultMessage", "setupSearchIndex", "config", "docs", "translation", "options", "feature", "setupSearchWorker", "url", "index", "configuration", "worker", "tx$", "Subject", "rx$", "watchWorker", "map", "message", "isSearchResultMessage", "result", "document", "share", "from", "data", "setupVersionSelector", "document$", "config", "configuration", "versions$", "requestJSON", "catchError", "EMPTY", "current$", "map", "versions", "current", "version", "aliases", "switchMap", "urls", "fromEvent", "filter", "ev", "withLatestFrom", "el", "url", "of", "fetchSitemap", "sitemap", "path", "getLocation", "setLocation", "combineLatest", "getElement", "renderVersionSelector", "_a", "outdated", "latest", "warning", "getComponentElements", "watchSearchQuery", "el", "rx$", "fn", "defaultTransform", "searchParams", "getLocation", "setToggle", "param$", "filter", "isSearchReadyMessage", "take", "map", "watchToggle", "active", "url", "value", "focus$", "watchElementFocus", "value$", "merge", "fromEvent", "delay", "startWith", "distinctUntilChanged", "combineLatest", "focus", "shareReplay", "mountSearchQuery", "tx$", "push$", "Subject", "done$", "takeLast", "distinctUntilKeyChanged", "translation", "takeUntil", "tap", "state", "finalize", "__spreadValues", "share", "mountSearchResult", "el", "rx$", "query$", "push$", "Subject", "boundary$", "watchElementBoundary", "filter", "meta", "getElement", "list", "ready$", "isSearchReadyMessage", "take", "withLatestFrom", "skipUntil", "items", "value", "translation", "round", "tap", "switchMap", "merge", "of", "bufferCount", "zipWith", "chunk", "result", "renderSearchResultItem", "isSearchResultMessage", "map", "data", "state", "finalize", "__spreadValues", "watchSearchShare", "_el", "query$", "map", "value", "url", "getLocation", "mountSearchShare", "el", "options", "push$", "Subject", "fromEvent", "ev", "tap", "state", "finalize", "__spreadValues", "mountSearchSuggest", "el", "rx$", "keyboard$", "push$", "Subject", "query", "getComponentElement", "query$", "merge", "fromEvent", "observeOn", "asyncScheduler", "map", "distinctUntilChanged", "combineLatestWith", "suggestions", "value", "words", "last", "filter", "mode", "key", "isSearchResultMessage", "data", "tap", "state", "finalize", "mountSearch", "el", "index$", "keyboard$", "config", "configuration", "url", "worker", "setupSearchWorker", "query", "getComponentElement", "result", "tx$", "rx$", "filter", "isSearchQueryMessage", "sample", "isSearchReadyMessage", "take", "mode", "key", "active", "getActiveElement", "anchors", "anchor", "getElements", "article", "best", "a", "b", "setToggle", "els", "i", "query$", "mountSearchQuery", "result$", "mountSearchResult", "merge", "mergeWith", "getComponentElements", "child", "mountSearchShare", "mountSearchSuggest", "err", "NEVER", "mountSearchHiglight", "el", "index$", "location$", "combineLatest", "startWith", "getLocation", "filter", "url", "map", "index", "setupSearchHighlighter", "fn", "_a", "nodes", "it", "node", "original", "replaced", "text", "childNodes", "h", "watchSidebar", "el", "viewport$", "main$", "parent", "adjust", "combineLatest", "map", "offset", "height", "y", "distinctUntilChanged", "a", "b", "mountSidebar", "_a", "_b", "header$", "options", "__objRest", "inner", "getElement", "getElementOffset", "defer", "push$", "Subject", "auditTime", "animationFrameScheduler", "withLatestFrom", "observeOn", "take", "item", "getElements", "container", "getElementContainer", "getElementSize", "tap", "state", "finalize", "__spreadValues", "fetchSourceFactsFromGitHub", "user", "repo", "url", "zip", "requestJSON", "catchError", "EMPTY", "map", "release", "defaultIfEmpty", "info", "__spreadValues", "fetchSourceFactsFromGitLab", "base", "project", "url", "requestJSON", "catchError", "EMPTY", "map", "star_count", "forks_count", "defaultIfEmpty", "fetchSourceFacts", "url", "match", "user", "repo", "fetchSourceFactsFromGitHub", "base", "slug", "fetchSourceFactsFromGitLab", "EMPTY", "fetch$", "watchSource", "el", "defer", "cached", "of", "getComponentElements", "consent", "EMPTY", "fetchSourceFacts", "tap", "facts", "catchError", "filter", "map", "shareReplay", "mountSource", "inner", "getElement", "push$", "Subject", "renderSourceFacts", "state", "finalize", "__spreadValues", "watchTabs", "el", "viewport$", "header$", "watchElementSize", "switchMap", "watchViewportAt", "map", "y", "distinctUntilKeyChanged", "mountTabs", "options", "defer", "push$", "Subject", "hidden", "feature", "of", "tap", "state", "finalize", "__spreadValues", "watchTableOfContents", "el", "viewport$", "header$", "table", "anchors", "getElements", "anchor", "id", "target", "getOptionalElement", "adjust$", "distinctUntilKeyChanged", "map", "height", "main", "getComponentElement", "grid", "getElement", "share", "watchElementSize", "switchMap", "body", "defer", "path", "of", "index", "offset", "a", "b", "combineLatestWith", "adjust", "scan", "prev", "next", "y", "size", "last", "distinctUntilChanged", "startWith", "bufferCount", "mountTableOfContents", "target$", "push$", "Subject", "done$", "takeLast", "feature", "smooth$", "merge", "debounceTime", "filter", "withLatestFrom", "behavior", "container", "getElementContainer", "getElementSize", "takeUntil", "skip", "repeat", "url", "getLocation", "active", "hash", "tap", "state", "finalize", "__spreadValues", "watchBackToTop", "_el", "viewport$", "main$", "target$", "direction$", "map", "y", "bufferCount", "a", "b", "distinctUntilChanged", "active$", "active", "combineLatest", "direction", "takeUntil", "skip", "endWith", "repeat", "hidden", "mountBackToTop", "el", "header$", "push$", "Subject", "done$", "takeLast", "distinctUntilKeyChanged", "height", "tap", "state", "finalize", "__spreadValues", "patchIndeterminate", "document$", "tablet$", "switchMap", "getElements", "tap", "el", "mergeMap", "fromEvent", "takeWhile", "map", "withLatestFrom", "tablet", "isAppleDevice", "patchScrollfix", "document$", "switchMap", "getElements", "tap", "el", "filter", "mergeMap", "fromEvent", "map", "top", "patchScrolllock", "viewport$", "tablet$", "combineLatest", "watchToggle", "map", "active", "tablet", "switchMap", "of", "delay", "withLatestFrom", "y", "value", "obj", "data", "key", "x", "y", "nodes", "parent", "i", "node", "document$", "watchDocument", "location$", "watchLocation", "target$", "watchLocationTarget", "keyboard$", "watchKeyboard", "viewport$", "watchViewport", "tablet$", "watchMedia", "screen$", "print$", "watchPrint", "config", "configuration", "index$", "requestJSON", "NEVER", "alert$", "Subject", "setupClipboardJS", "feature", "setupInstantLoading", "_a", "setupVersionSelector", "merge", "delay", "setToggle", "filter", "mode", "key", "prev", "getOptionalElement", "next", "patchIndeterminate", "patchScrollfix", "patchScrolllock", "header$", "watchHeader", "getComponentElement", "main$", "map", "switchMap", "el", "watchMain", "shareReplay", "control$", "getComponentElements", "mountConsent", "mountDialog", "mountHeader", "mountPalette", "mountSearch", "mountSource", "content$", "defer", "mountAnnounce", "mountContent", "mountSearchHiglight", "EMPTY", "mountHeaderTitle", "at", "mountSidebar", "mountTabs", "mountTableOfContents", "mountBackToTop", "component$", "mergeWith"] +} diff --git a/assets/javascripts/extra/bundle.5f09fbc3.min.js b/assets/javascripts/extra/bundle.5f09fbc3.min.js new file mode 100644 index 000000000..48b752cd0 --- /dev/null +++ b/assets/javascripts/extra/bundle.5f09fbc3.min.js @@ -0,0 +1,18 @@ +"use strict";(()=>{var Je=Object.create;var qr=Object.defineProperty;var $e=Object.getOwnPropertyDescriptor;var Qe=Object.getOwnPropertyNames;var Xe=Object.getPrototypeOf,Ze=Object.prototype.hasOwnProperty;var rt=(r,o)=>()=>(o||r((o={exports:{}}).exports,o),o.exports);var et=(r,o,t,e)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of Qe(o))!Ze.call(r,n)&&n!==t&&qr(r,n,{get:()=>o[n],enumerable:!(e=$e(o,n))||e.enumerable});return r};var tt=(r,o,t)=>(t=r!=null?Je(Xe(r)):{},et(o||!r||!r.__esModule?qr(t,"default",{value:r,enumerable:!0}):t,r));var me=rt((Tt,er)=>{/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */var Hr,Kr,Jr,$r,Qr,Xr,Zr,re,ee,Z,Ar,te,oe,ne,k,ie,fe,ae,ue,ce,se,pe,le,rr;(function(r){var o=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(e){r(t(o,t(e)))}):typeof er=="object"&&typeof er.exports=="object"?r(t(o,t(er.exports))):r(t(o));function t(e,n){return e!==o&&(typeof Object.create=="function"?Object.defineProperty(e,"__esModule",{value:!0}):e.__esModule=!0),function(i,f){return e[i]=n?n(i,f):f}}})(function(r){var o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,n){e.__proto__=n}||function(e,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i])};Hr=function(e,n){if(typeof n!="function"&&n!==null)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");o(e,n);function i(){this.constructor=e}e.prototype=n===null?Object.create(n):(i.prototype=n.prototype,new i)},Kr=Object.assign||function(e){for(var n,i=1,f=arguments.length;i=0;s--)(c=e[s])&&(a=(u<3?c(a):u>3?c(n,i,a):c(n,i))||a);return u>3&&a&&Object.defineProperty(n,i,a),a},Qr=function(e,n){return function(i,f){n(i,f,e)}},Xr=function(e,n){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(e,n)},Zr=function(e,n,i,f){function u(a){return a instanceof i?a:new i(function(c){c(a)})}return new(i||(i=Promise))(function(a,c){function s(y){try{p(f.next(y))}catch(g){c(g)}}function d(y){try{p(f.throw(y))}catch(g){c(g)}}function p(y){y.done?a(y.value):u(y.value).then(s,d)}p((f=f.apply(e,n||[])).next())})},re=function(e,n){var i={label:0,sent:function(){if(a[0]&1)throw a[1];return a[1]},trys:[],ops:[]},f,u,a,c;return c={next:s(0),throw:s(1),return:s(2)},typeof Symbol=="function"&&(c[Symbol.iterator]=function(){return this}),c;function s(p){return function(y){return d([p,y])}}function d(p){if(f)throw new TypeError("Generator is already executing.");for(;i;)try{if(f=1,u&&(a=p[0]&2?u.return:p[0]?u.throw||((a=u.return)&&a.call(u),0):u.next)&&!(a=a.call(u,p[1])).done)return a;switch(u=0,a&&(p=[p[0]&2,a.value]),p[0]){case 0:case 1:a=p;break;case 4:return i.label++,{value:p[1],done:!1};case 5:i.label++,u=p[1],p=[0];continue;case 7:p=i.ops.pop(),i.trys.pop();continue;default:if(a=i.trys,!(a=a.length>0&&a[a.length-1])&&(p[0]===6||p[0]===2)){i=0;continue}if(p[0]===3&&(!a||p[1]>a[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[f++],done:!e}}};throw new TypeError(n?"Object is not iterable.":"Symbol.iterator is not defined.")},Ar=function(e,n){var i=typeof Symbol=="function"&&e[Symbol.iterator];if(!i)return e;var f=i.call(e),u,a=[],c;try{for(;(n===void 0||n-- >0)&&!(u=f.next()).done;)a.push(u.value)}catch(s){c={error:s}}finally{try{u&&!u.done&&(i=f.return)&&i.call(f)}finally{if(c)throw c.error}}return a},te=function(){for(var e=[],n=0;n1||s(m,P)})})}function s(m,P){try{d(f[m](P))}catch(j){g(a[0][3],j)}}function d(m){m.value instanceof k?Promise.resolve(m.value.v).then(p,y):g(a[0][2],m)}function p(m){s("next",m)}function y(m){s("throw",m)}function g(m,P){m(P),a.shift(),a.length&&s(a[0][0],a[0][1])}},fe=function(e){var n,i;return n={},f("next"),f("throw",function(u){throw u}),f("return"),n[Symbol.iterator]=function(){return this},n;function f(u,a){n[u]=e[u]?function(c){return(i=!i)?{value:k(e[u](c)),done:u==="return"}:a?a(c):c}:a}},ae=function(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var n=e[Symbol.asyncIterator],i;return n?n.call(e):(e=typeof Z=="function"?Z(e):e[Symbol.iterator](),i={},f("next"),f("throw"),f("return"),i[Symbol.asyncIterator]=function(){return this},i);function f(a){i[a]=e[a]&&function(c){return new Promise(function(s,d){c=e[a](c),u(s,d,c.done,c.value)})}}function u(a,c,s,d){Promise.resolve(d).then(function(p){a({value:p,done:s})},c)}},ue=function(e,n){return Object.defineProperty?Object.defineProperty(e,"raw",{value:n}):e.raw=n,e};var t=Object.create?function(e,n){Object.defineProperty(e,"default",{enumerable:!0,value:n})}:function(e,n){e.default=n};ce=function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var i in e)i!=="default"&&Object.prototype.hasOwnProperty.call(e,i)&&rr(n,e,i);return t(n,e),n},se=function(e){return e&&e.__esModule?e:{default:e}},pe=function(e,n,i,f){if(i==="a"&&!f)throw new TypeError("Private accessor was defined without a getter");if(typeof n=="function"?e!==n||!f:!n.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?f:i==="a"?f.call(e):f?f.value:n.get(e)},le=function(e,n,i,f,u){if(f==="m")throw new TypeError("Private method is not writable");if(f==="a"&&!u)throw new TypeError("Private accessor was defined without a setter");if(typeof n=="function"?e!==n||!u:!n.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return f==="a"?u.call(e,i):u?u.value=i:n.set(e,i),i},r("__extends",Hr),r("__assign",Kr),r("__rest",Jr),r("__decorate",$r),r("__param",Qr),r("__metadata",Xr),r("__awaiter",Zr),r("__generator",re),r("__exportStar",ee),r("__createBinding",rr),r("__values",Z),r("__read",Ar),r("__spread",te),r("__spreadArrays",oe),r("__spreadArray",ne),r("__await",k),r("__asyncGenerator",ie),r("__asyncDelegator",fe),r("__asyncValues",ae),r("__makeTemplateObject",ue),r("__importStar",ce),r("__importDefault",se),r("__classPrivateFieldGet",pe),r("__classPrivateFieldSet",le)})});var de=tt(me(),1),{__extends:_,__assign:Pt,__rest:jt,__decorate:Ft,__param:Mt,__metadata:Ct,__awaiter:he,__generator:tr,__exportStar:Lt,__createBinding:Rt,__values:M,__read:w,__spread:kt,__spreadArrays:Ut,__spreadArray:S,__await:or,__asyncGenerator:ve,__asyncDelegator:Wt,__asyncValues:be,__makeTemplateObject:Dt,__importStar:Vt,__importDefault:Bt,__classPrivateFieldGet:Gt,__classPrivateFieldSet:Nt}=de.default;function l(r){return typeof r=="function"}function nr(r){var o=function(e){Error.call(e),e.stack=new Error().stack},t=r(o);return t.prototype=Object.create(Error.prototype),t.prototype.constructor=t,t}var ir=nr(function(r){return function(t){r(this),this.message=t?t.length+` errors occurred during unsubscription: +`+t.map(function(e,n){return n+1+") "+e.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=t}});function C(r,o){if(r){var t=r.indexOf(o);0<=t&&r.splice(t,1)}}var F=function(){function r(o){this.initialTeardown=o,this.closed=!1,this._parentage=null,this._finalizers=null}return r.prototype.unsubscribe=function(){var o,t,e,n,i;if(!this.closed){this.closed=!0;var f=this._parentage;if(f)if(this._parentage=null,Array.isArray(f))try{for(var u=M(f),a=u.next();!a.done;a=u.next()){var c=a.value;c.remove(this)}}catch(m){o={error:m}}finally{try{a&&!a.done&&(t=u.return)&&t.call(u)}finally{if(o)throw o.error}}else f.remove(this);var s=this.initialTeardown;if(l(s))try{s()}catch(m){i=m instanceof ir?m.errors:[m]}var d=this._finalizers;if(d){this._finalizers=null;try{for(var p=M(d),y=p.next();!y.done;y=p.next()){var g=y.value;try{ye(g)}catch(m){i=i!=null?i:[],m instanceof ir?i=S(S([],w(i)),w(m.errors)):i.push(m)}}}catch(m){e={error:m}}finally{try{y&&!y.done&&(n=p.return)&&n.call(p)}finally{if(e)throw e.error}}}if(i)throw new ir(i)}},r.prototype.add=function(o){var t;if(o&&o!==this)if(this.closed)ye(o);else{if(o instanceof r){if(o.closed||o._hasParent(this))return;o._addParent(this)}(this._finalizers=(t=this._finalizers)!==null&&t!==void 0?t:[]).push(o)}},r.prototype._hasParent=function(o){var t=this._parentage;return t===o||Array.isArray(t)&&t.includes(o)},r.prototype._addParent=function(o){var t=this._parentage;this._parentage=Array.isArray(t)?(t.push(o),t):t?[t,o]:o},r.prototype._removeParent=function(o){var t=this._parentage;t===o?this._parentage=null:Array.isArray(t)&&C(t,o)},r.prototype.remove=function(o){var t=this._finalizers;t&&C(t,o),o instanceof r&&o._removeParent(this)},r.EMPTY=function(){var o=new r;return o.closed=!0,o}(),r}();var Ir=F.EMPTY;function fr(r){return r instanceof F||r&&"closed"in r&&l(r.remove)&&l(r.add)&&l(r.unsubscribe)}function ye(r){l(r)?r():r.unsubscribe()}var O={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var U={setTimeout:function(r,o){for(var t=[],e=2;e0},enumerable:!1,configurable:!0}),o.prototype._trySubscribe=function(t){return this._throwIfClosed(),r.prototype._trySubscribe.call(this,t)},o.prototype._subscribe=function(t){return this._throwIfClosed(),this._checkFinalizedStatuses(t),this._innerSubscribe(t)},o.prototype._innerSubscribe=function(t){var e=this,n=this,i=n.hasError,f=n.isStopped,u=n.observers;return i||f?Ir:(this.currentObservers=null,u.push(t),new F(function(){e.currentObservers=null,C(u,t)}))},o.prototype._checkFinalizedStatuses=function(t){var e=this,n=e.hasError,i=e.thrownError,f=e.isStopped;n?t.error(i):f&&t.complete()},o.prototype.asObservable=function(){var t=new b;return t.source=this,t},o.create=function(t,e){return new Ae(t,e)},o}(b);var Ae=function(r){_(o,r);function o(t,e){var n=r.call(this)||this;return n.destination=t,n.source=e,n}return o.prototype.next=function(t){var e,n;(n=(e=this.destination)===null||e===void 0?void 0:e.next)===null||n===void 0||n.call(e,t)},o.prototype.error=function(t){var e,n;(n=(e=this.destination)===null||e===void 0?void 0:e.error)===null||n===void 0||n.call(e,t)},o.prototype.complete=function(){var t,e;(e=(t=this.destination)===null||t===void 0?void 0:t.complete)===null||e===void 0||e.call(t)},o.prototype._subscribe=function(t){var e,n;return(n=(e=this.source)===null||e===void 0?void 0:e.subscribe(t))!==null&&n!==void 0?n:Ir},o}(Fr);var J={now:function(){return(J.delegate||Date).now()},delegate:void 0};var Mr=function(r){_(o,r);function o(t,e,n){t===void 0&&(t=1/0),e===void 0&&(e=1/0),n===void 0&&(n=J);var i=r.call(this)||this;return i._bufferSize=t,i._windowTime=e,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=e===1/0,i._bufferSize=Math.max(1,t),i._windowTime=Math.max(1,e),i}return o.prototype.next=function(t){var e=this,n=e.isStopped,i=e._buffer,f=e._infiniteTimeWindow,u=e._timestampProvider,a=e._windowTime;n||(i.push(t),!f&&i.push(u.now()+a)),this._trimBuffer(),r.prototype.next.call(this,t)},o.prototype._subscribe=function(t){this._throwIfClosed(),this._trimBuffer();for(var e=this._innerSubscribe(t),n=this,i=n._infiniteTimeWindow,f=n._buffer,u=f.slice(),a=0;a{sessionStorage.setItem("\u1D34\u2092\u1D34\u2092\u1D34\u2092",`${t}`),r.hidden=!t}),o.next(JSON.parse(sessionStorage.getItem("\u1D34\u2092\u1D34\u2092\u1D34\u2092")||"true")),z(r,"click").pipe(zr(o)).subscribe(([,t])=>o.next(!t)),kr(250).pipe(gr(o.pipe(X(t=>!t))),H(75),Nr({delay:()=>o.pipe(X(t=>t))}),T(()=>{let t=document.createElement("div");return t.className="\u1D34\u2092\u1D34\u2092\u1D34\u2092",t.ariaHidden="true",Ke.appendChild(t),Ur(Wr,Rr(t)).pipe(Gr(()=>t.remove()),gr(o.pipe(X(e=>!e))),Yr(e=>z(e,"click").pipe(Er(()=>e.classList.add("\u1D34\u2092\u1D34\u2092\u1D34\u2092--\u1D4D\u2092\u1D57\uA700\u1D34\u2090")),Vr(1e3),Er(()=>e.classList.remove("\u1D34\u2092\u1D34\u2092\u1D34\u2092--\u1D4D\u2092\u1D57\uA700\u1D34\u2090")))))})).subscribe()}})(); +//# sourceMappingURL=bundle.5f09fbc3.min.js.map + diff --git a/assets/javascripts/extra/bundle.5f09fbc3.min.js.map b/assets/javascripts/extra/bundle.5f09fbc3.min.js.map new file mode 100644 index 000000000..24f367460 --- /dev/null +++ b/assets/javascripts/extra/bundle.5f09fbc3.min.js.map @@ -0,0 +1,8 @@ +{ + "version": 3, + "sources": ["node_modules/rxjs/node_modules/tslib/tslib.js", "node_modules/rxjs/node_modules/tslib/modules/index.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/interval.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "src/assets/javascripts/extra/bundle.ts"], + "sourceRoot": "../../../..", + "sourcesContent": ["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __spreadArrays;\r\nvar __spreadArray;\r\nvar __await;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\nvar __makeTemplateObject;\r\nvar __importStar;\r\nvar __importDefault;\r\nvar __classPrivateFieldGet;\r\nvar __classPrivateFieldSet;\r\nvar __createBinding;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n if (exports !== root) {\r\n if (typeof Object.create === \"function\") {\r\n Object.defineProperty(exports, \"__esModule\", { value: true });\r\n }\r\n else {\r\n exports.__esModule = true;\r\n }\r\n }\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n };\r\n\r\n __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n }) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n });\r\n\r\n __values = function (o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n /** @deprecated */\r\n __spreadArrays = function () {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n };\r\n\r\n __spreadArray = function (to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n };\r\n\r\n __await = function (v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n };\r\n\r\n __makeTemplateObject = function (cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n };\r\n\r\n var __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n }) : function(o, v) {\r\n o[\"default\"] = v;\r\n };\r\n\r\n __importStar = function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n };\r\n\r\n __importDefault = function (mod) {\r\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\r\n };\r\n\r\n __classPrivateFieldGet = function (receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n };\r\n\r\n __classPrivateFieldSet = function (receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__createBinding\", __createBinding);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__spreadArrays\", __spreadArrays);\r\n exporter(\"__spreadArray\", __spreadArray);\r\n exporter(\"__await\", __await);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n exporter(\"__makeTemplateObject\", __makeTemplateObject);\r\n exporter(\"__importStar\", __importStar);\r\n exporter(\"__importDefault\", __importDefault);\r\n exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\r\n exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\r\n});\r\n", "import tslib from '../tslib.js';\r\nconst {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n} = tslib;\r\nexport {\r\n __extends,\r\n __assign,\r\n __rest,\r\n __decorate,\r\n __param,\r\n __metadata,\r\n __awaiter,\r\n __generator,\r\n __exportStar,\r\n __createBinding,\r\n __values,\r\n __read,\r\n __spread,\r\n __spreadArrays,\r\n __spreadArray,\r\n __await,\r\n __asyncGenerator,\r\n __asyncDelegator,\r\n __asyncValues,\r\n __makeTemplateObject,\r\n __importStar,\r\n __importDefault,\r\n __classPrivateFieldGet,\r\n __classPrivateFieldSet,\r\n};\r\n", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n NEVER,\n ReplaySubject,\n delay,\n distinctUntilChanged,\n filter,\n finalize,\n fromEvent,\n interval,\n merge,\n mergeMap,\n of,\n repeat,\n switchMap,\n take,\n takeUntil,\n tap,\n withLatestFrom\n} from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Script\n * ------------------------------------------------------------------------- */\n\n/* Append container for instances */\nconst container = document.createElement(\"div\")\ndocument.body.appendChild(container)\n\n/* Append button next to palette toggle */\nconst header = document.querySelector(\".md-header__option\")\nif (header) {\n const button = document.createElement(\"button\")\n button.className = \"md-header__button md-icon \u1D34\u2092\u1D34\u2092\u1D34\u2092__button\"\n if (header.parentElement)\n header.parentElement.insertBefore(button, header)\n\n /* Toggle animation */\n const on$ = new ReplaySubject(1)\n on$\n .pipe(\n distinctUntilChanged()\n )\n .subscribe(on => {\n sessionStorage.setItem(\"\u1D34\u2092\u1D34\u2092\u1D34\u2092\", `${on}`)\n button.hidden = !on\n })\n\n /* Load state from session storage */\n on$.next(JSON.parse(sessionStorage.getItem(\"\u1D34\u2092\u1D34\u2092\u1D34\u2092\") || \"true\"))\n fromEvent(button, \"click\")\n .pipe(\n withLatestFrom(on$)\n )\n .subscribe(([, on]) => on$.next(!on))\n\n /* Generate instances */\n interval(250)\n .pipe(\n takeUntil(on$.pipe(filter(on => !on))),\n take(75),\n repeat({ delay: () => on$.pipe(filter(on => on)) }),\n mergeMap(() => {\n const instance = document.createElement(\"div\")\n instance.className = \"\u1D34\u2092\u1D34\u2092\u1D34\u2092\"\n instance.ariaHidden = \"true\"\n container.appendChild(instance)\n return merge(NEVER, of(instance))\n .pipe(\n finalize(() => instance.remove()),\n takeUntil(on$.pipe(filter(on => !on))),\n switchMap(el => fromEvent(el, \"click\")\n .pipe(\n tap(() => el.classList.add(\"\u1D34\u2092\u1D34\u2092\u1D34\u2092--\u1D4D\u2092\u1D57\uA700\u1D34\u2090\")),\n delay(1000),\n tap(() => el.classList.remove(\"\u1D34\u2092\u1D34\u2092\u1D34\u2092--\u1D4D\u2092\u1D57\uA700\u1D34\u2090\"))\n )\n )\n )\n })\n )\n .subscribe()\n}\n"], + "mappings": "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", + "names": ["require_tslib", "__commonJSMin", "exports", "module", "__extends", "__assign", "__rest", "__decorate", "__param", "__metadata", "__awaiter", "__generator", "__exportStar", "__values", "__read", "__spread", "__spreadArrays", "__spreadArray", "__await", "__asyncGenerator", "__asyncDelegator", "__asyncValues", "__makeTemplateObject", "__importStar", "__importDefault", "__classPrivateFieldGet", "__classPrivateFieldSet", "__createBinding", "factory", "root", "createExporter", "previous", "id", "v", "exporter", "extendStatics", "d", "b", "p", "__", "t", "s", "n", "e", "i", "decorators", "target", "key", "desc", "c", "r", "paramIndex", "decorator", "metadataKey", "metadataValue", "thisArg", "_arguments", "P", "generator", "adopt", "value", "resolve", "reject", "fulfilled", "step", "rejected", "result", "body", "_", "y", "g", "verb", "op", "m", "o", "k", "k2", "ar", "error", "il", "j", "jl", "to", "from", "pack", "l", "q", "a", "resume", "settle", "fulfill", "f", "cooked", "raw", "__setModuleDefault", "mod", "receiver", "state", "kind", "import_tslib", "__extends", "__assign", "__rest", "__decorate", "__param", "__metadata", "__awaiter", "__generator", "__exportStar", "__createBinding", "__values", "__read", "__spread", "__spreadArrays", "__spreadArray", "__await", "__asyncGenerator", "__asyncDelegator", "__asyncValues", "__makeTemplateObject", "__importStar", "__importDefault", "__classPrivateFieldGet", "__classPrivateFieldSet", "tslib", "isFunction", "value", "createErrorClass", "createImpl", "_super", "instance", "ctorFunc", "UnsubscriptionError", "createErrorClass", "_super", "errors", "err", "i", "arrRemove", "arr", "item", "index", "Subscription", "initialTeardown", "errors", "_parentage", "_parentage_1", "__values", "_parentage_1_1", "parent_1", "initialFinalizer", "isFunction", "e", "UnsubscriptionError", "_finalizers", "_finalizers_1", "_finalizers_1_1", "finalizer", "execFinalizer", "err", "__spreadArray", "__read", "teardown", "_a", "parent", "arrRemove", "empty", "EMPTY_SUBSCRIPTION", "Subscription", "isSubscription", "value", "isFunction", "execFinalizer", "finalizer", "config", "timeoutProvider", "handler", "timeout", "args", "_i", "delegate", "__spreadArray", "__read", "handle", "reportUnhandledError", "err", "timeoutProvider", "onUnhandledError", "config", "noop", "COMPLETE_NOTIFICATION", "createNotification", "errorNotification", "error", "nextNotification", "value", "kind", "context", "errorContext", "cb", "config", "isRoot", "_a", "errorThrown", "error", "captureError", "err", "Subscriber", "_super", "__extends", "destination", "_this", "isSubscription", "EMPTY_OBSERVER", "next", "error", "complete", "SafeSubscriber", "value", "handleStoppedNotification", "nextNotification", "err", "errorNotification", "COMPLETE_NOTIFICATION", "Subscription", "_bind", "bind", "fn", "thisArg", "ConsumerObserver", "partialObserver", "value", "error", "handleUnhandledError", "err", "SafeSubscriber", "_super", "__extends", "observerOrNext", "complete", "_this", "isFunction", "context_1", "config", "Subscriber", "handleUnhandledError", "error", "config", "captureError", "reportUnhandledError", "defaultErrorHandler", "err", "handleStoppedNotification", "notification", "subscriber", "onStoppedNotification", "timeoutProvider", "EMPTY_OBSERVER", "noop", "observable", "identity", "x", "pipeFromArray", "fns", "identity", "input", "prev", "fn", "Observable", "subscribe", "operator", "observable", "observerOrNext", "error", "complete", "_this", "subscriber", "isSubscriber", "SafeSubscriber", "errorContext", "_a", "source", "sink", "err", "next", "promiseCtor", "getPromiseCtor", "resolve", "reject", "value", "operations", "_i", "pipeFromArray", "x", "getPromiseCtor", "promiseCtor", "_a", "config", "isObserver", "value", "isFunction", "isSubscriber", "Subscriber", "isSubscription", "hasLift", "source", "isFunction", "operate", "init", "liftedSource", "err", "createOperatorSubscriber", "destination", "onNext", "onComplete", "onError", "onFinalize", "OperatorSubscriber", "_super", "__extends", "shouldUnsubscribe", "_this", "value", "err", "closed_1", "_a", "Subscriber", "ObjectUnsubscribedError", "createErrorClass", "_super", "Subject", "_super", "__extends", "_this", "operator", "subject", "AnonymousSubject", "ObjectUnsubscribedError", "value", "errorContext", "_b", "__values", "_c", "observer", "err", "observers", "_a", "subscriber", "hasError", "isStopped", "EMPTY_SUBSCRIPTION", "Subscription", "arrRemove", "thrownError", "observable", "Observable", "destination", "source", "AnonymousSubject", "_super", "__extends", "destination", "source", "_this", "value", "_b", "_a", "err", "subscriber", "EMPTY_SUBSCRIPTION", "Subject", "dateTimestampProvider", "ReplaySubject", "_super", "__extends", "_bufferSize", "_windowTime", "_timestampProvider", "dateTimestampProvider", "_this", "value", "_a", "isStopped", "_buffer", "_infiniteTimeWindow", "subscriber", "subscription", "copy", "i", "adjustedBufferSize", "now", "last", "Subject", "Action", "_super", "__extends", "scheduler", "work", "state", "delay", "Subscription", "intervalProvider", "handler", "timeout", "args", "_i", "delegate", "__spreadArray", "__read", "handle", "AsyncAction", "_super", "__extends", "scheduler", "work", "_this", "state", "delay", "id", "_a", "_id", "intervalProvider", "_scheduler", "error", "_delay", "errored", "errorValue", "e", "actions", "arrRemove", "Action", "Scheduler", "schedulerActionCtor", "now", "work", "delay", "state", "dateTimestampProvider", "AsyncScheduler", "_super", "__extends", "SchedulerAction", "now", "Scheduler", "_this", "action", "actions", "error", "asyncScheduler", "AsyncScheduler", "AsyncAction", "async", "EMPTY", "Observable", "subscriber", "isScheduler", "value", "isFunction", "last", "arr", "popResultSelector", "args", "isFunction", "popScheduler", "isScheduler", "popNumber", "defaultValue", "isArrayLike", "x", "isPromise", "value", "isFunction", "isInteropObservable", "input", "isFunction", "observable", "isAsyncIterable", "obj", "isFunction", "createInvalidObservableTypeError", "input", "getSymbolIterator", "iterator", "isIterable", "input", "isFunction", "iterator", "readableStreamLikeToAsyncGenerator", "readableStream", "reader", "__await", "_a", "_b", "value", "done", "isReadableStreamLike", "obj", "isFunction", "innerFrom", "input", "Observable", "isInteropObservable", "fromInteropObservable", "isArrayLike", "fromArrayLike", "isPromise", "fromPromise", "isAsyncIterable", "fromAsyncIterable", "isIterable", "fromIterable", "isReadableStreamLike", "fromReadableStreamLike", "createInvalidObservableTypeError", "obj", "subscriber", "obs", "observable", "isFunction", "array", "i", "promise", "value", "err", "reportUnhandledError", "iterable", "iterable_1", "__values", "iterable_1_1", "asyncIterable", "process", "readableStream", "readableStreamLikeToAsyncGenerator", "asyncIterable_1", "__asyncValues", "asyncIterable_1_1", "executeSchedule", "parentSubscription", "scheduler", "work", "delay", "repeat", "scheduleSubscription", "observeOn", "scheduler", "delay", "operate", "source", "subscriber", "createOperatorSubscriber", "value", "executeSchedule", "err", "subscribeOn", "scheduler", "delay", "operate", "source", "subscriber", "scheduleObservable", "input", "scheduler", "innerFrom", "subscribeOn", "observeOn", "schedulePromise", "input", "scheduler", "innerFrom", "subscribeOn", "observeOn", "scheduleArray", "input", "scheduler", "Observable", "subscriber", "i", "scheduleIterable", "input", "scheduler", "Observable", "subscriber", "iterator", "executeSchedule", "value", "done", "_a", "err", "isFunction", "scheduleAsyncIterable", "input", "scheduler", "Observable", "subscriber", "executeSchedule", "iterator", "result", "scheduleReadableStreamLike", "input", "scheduler", "scheduleAsyncIterable", "readableStreamLikeToAsyncGenerator", "scheduled", "input", "scheduler", "isInteropObservable", "scheduleObservable", "isArrayLike", "scheduleArray", "isPromise", "schedulePromise", "isAsyncIterable", "scheduleAsyncIterable", "isIterable", "scheduleIterable", "isReadableStreamLike", "scheduleReadableStreamLike", "createInvalidObservableTypeError", "from", "input", "scheduler", "scheduled", "innerFrom", "of", "args", "_i", "scheduler", "popScheduler", "from", "isValidDate", "value", "map", "project", "thisArg", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "isArray", "callOrApply", "fn", "args", "__spreadArray", "__read", "mapOneOrManyArgs", "map", "mergeInternals", "source", "subscriber", "project", "concurrent", "onBeforeNext", "expand", "innerSubScheduler", "additionalFinalizer", "buffer", "active", "index", "isComplete", "checkComplete", "outerNext", "value", "doInnerSub", "innerComplete", "innerFrom", "createOperatorSubscriber", "innerValue", "bufferedValue", "executeSchedule", "err", "mergeMap", "project", "resultSelector", "concurrent", "isFunction", "a", "i", "map", "b", "ii", "innerFrom", "operate", "source", "subscriber", "mergeInternals", "mergeAll", "concurrent", "mergeMap", "identity", "concatAll", "mergeAll", "concat", "args", "_i", "concatAll", "from", "popScheduler", "nodeEventEmitterMethods", "eventTargetMethods", "jqueryMethods", "fromEvent", "target", "eventName", "options", "resultSelector", "isFunction", "mapOneOrManyArgs", "_a", "__read", "isEventTarget", "methodName", "handler", "isNodeStyleEventEmitter", "toCommonHandlerRegistry", "isJQueryStyleEventEmitter", "add", "remove", "isArrayLike", "mergeMap", "subTarget", "innerFrom", "Observable", "subscriber", "args", "_i", "timer", "dueTime", "intervalOrScheduler", "scheduler", "async", "intervalDuration", "isScheduler", "Observable", "subscriber", "due", "isValidDate", "n", "interval", "period", "scheduler", "asyncScheduler", "timer", "merge", "args", "_i", "scheduler", "popScheduler", "concurrent", "popNumber", "sources", "innerFrom", "mergeAll", "from", "EMPTY", "NEVER", "Observable", "noop", "filter", "predicate", "thisArg", "operate", "source", "subscriber", "index", "createOperatorSubscriber", "value", "take", "count", "EMPTY", "operate", "source", "subscriber", "seen", "createOperatorSubscriber", "value", "ignoreElements", "operate", "source", "subscriber", "createOperatorSubscriber", "noop", "mapTo", "value", "map", "delayWhen", "delayDurationSelector", "subscriptionDelay", "source", "concat", "take", "ignoreElements", "mergeMap", "value", "index", "mapTo", "delay", "due", "scheduler", "asyncScheduler", "duration", "timer", "delayWhen", "distinctUntilChanged", "comparator", "keySelector", "identity", "defaultCompare", "operate", "source", "subscriber", "previousKey", "first", "createOperatorSubscriber", "value", "currentKey", "a", "b", "finalize", "callback", "operate", "source", "subscriber", "repeat", "countOrConfig", "count", "delay", "_a", "EMPTY", "operate", "source", "subscriber", "soFar", "sourceSub", "resubscribe", "notifier", "timer", "innerFrom", "notifierSubscriber_1", "createOperatorSubscriber", "subscribeToSource", "syncUnsub", "switchMap", "project", "resultSelector", "operate", "source", "subscriber", "innerSubscriber", "index", "isComplete", "checkComplete", "createOperatorSubscriber", "value", "innerIndex", "outerIndex", "innerFrom", "innerValue", "takeUntil", "notifier", "operate", "source", "subscriber", "innerFrom", "createOperatorSubscriber", "noop", "tap", "observerOrNext", "error", "complete", "tapObserver", "isFunction", "operate", "source", "subscriber", "_a", "isUnsub", "createOperatorSubscriber", "value", "err", "_b", "identity", "withLatestFrom", "inputs", "_i", "project", "popResultSelector", "operate", "source", "subscriber", "len", "otherValues", "hasValue", "ready", "i", "innerFrom", "createOperatorSubscriber", "value", "identity", "noop", "values", "__spreadArray", "__read", "container", "header", "button", "on$", "ReplaySubject", "distinctUntilChanged", "on", "fromEvent", "withLatestFrom", "interval", "takeUntil", "filter", "take", "repeat", "mergeMap", "instance", "merge", "NEVER", "of", "finalize", "switchMap", "el", "tap", "delay"] +} diff --git a/assets/javascripts/lunr/min/lunr.ar.min.js b/assets/javascripts/lunr/min/lunr.ar.min.js new file mode 100644 index 000000000..9b06c26c1 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ar.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ar=function(){this.pipeline.reset(),this.pipeline.add(e.ar.trimmer,e.ar.stopWordFilter,e.ar.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ar.stemmer))},e.ar.wordCharacters="ء-ٛٱـ",e.ar.trimmer=e.trimmerSupport.generateTrimmer(e.ar.wordCharacters),e.Pipeline.registerFunction(e.ar.trimmer,"trimmer-ar"),e.ar.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ف ك ب و س ل ن ا ي ت",pre2:"ال لل",pre3:"بال وال فال تال كال ولل",pre4:"فبال كبال وبال وكال"},e.suf={suf1:"ه ك ت ن ا ي",suf2:"نك نه ها وك يا اه ون ين تن تم نا وا ان كم كن ني نن ما هم هن تك ته ات يه",suf3:"تين كهم نيه نهم ونه وها يهم ونا ونك وني وهم تكم تنا تها تني تهم كما كها ناه نكم هنا تان يها",suf4:"كموه ناها ونني ونهم تكما تموه تكاه كماه ناكم ناهم نيها وننا"},e.patterns=JSON.parse('{"pt43":[{"pt":[{"c":"ا","l":1}]},{"pt":[{"c":"ا,ت,ن,ي","l":0}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"و","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ل","l":2,"m":3}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ي","l":2}],"mPt":[{"c":"ف","l":0,"m":0},{"c":"ع","l":1,"m":1},{"c":"ا","l":2},{"c":"ل","l":3,"m":3}]},{"pt":[{"c":"م","l":0}]}],"pt53":[{"pt":[{"c":"ت","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":3},{"c":"ل","l":3,"m":4},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":0},{"c":"ا","l":3}],"mPt":[{"c":"ف","l":0,"m":1},{"c":"ع","l":1,"m":2},{"c":"ل","l":2,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ن","l":4}]},{"pt":[{"c":"ت","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"م","l":0},{"c":"و","l":3}]},{"pt":[{"c":"ا","l":1},{"c":"و","l":3}]},{"pt":[{"c":"و","l":1},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ي","l":3}]},{"pt":[{"c":"ا","l":2},{"c":"ن","l":3}]},{"pt":[{"c":"م","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"م","l":0},{"c":"ا","l":2}]},{"pt":[{"c":"م","l":1},{"c":"ا","l":3}]},{"pt":[{"c":"ي,ت,ا,ن","l":0},{"c":"ت","l":1}],"mPt":[{"c":"ف","l":0,"m":2},{"c":"ع","l":1,"m":3},{"c":"ا","l":2},{"c":"ل","l":3,"m":4}]},{"pt":[{"c":"ت,ي,ا,ن","l":0},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ت","l":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":2},{"c":"ي","l":3}]},{"pt":[{"c":"ا,ي,ت,ن","l":0},{"c":"ن","l":1}],"mPt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ف","l":2,"m":2},{"c":"ع","l":3,"m":3},{"c":"ا","l":4},{"c":"ل","l":5,"m":4}]},{"pt":[{"c":"ا","l":3},{"c":"ء","l":4}]}],"pt63":[{"pt":[{"c":"ا","l":0},{"c":"ت","l":2},{"c":"ا","l":4}]},{"pt":[{"c":"ا,ت,ن,ي","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ا,ن,ت,ي","l":0},{"c":"و","l":3}]},{"pt":[{"c":"م","l":0},{"c":"س","l":1},{"c":"ت","l":2}],"mPt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ف","l":3,"m":3},{"c":"ع","l":4,"m":4},{"c":"ا","l":5},{"c":"ل","l":6,"m":5}]},{"pt":[{"c":"ي","l":1},{"c":"ي","l":3},{"c":"ا","l":4},{"c":"ء","l":5}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":1},{"c":"ا","l":4}]}],"pt54":[{"pt":[{"c":"ت","l":0}]},{"pt":[{"c":"ا,ي,ت,ن","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"م","l":0}],"mPt":[{"c":"ا","l":0},{"c":"ف","l":1,"m":1},{"c":"ع","l":2,"m":2},{"c":"ل","l":3,"m":3},{"c":"ر","l":4,"m":4},{"c":"ا","l":5},{"c":"ر","l":6,"m":4}]},{"pt":[{"c":"ا","l":2}]},{"pt":[{"c":"ا","l":0},{"c":"ن","l":2}]}],"pt64":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":4}]},{"pt":[{"c":"م","l":0},{"c":"ت","l":1}]}],"pt73":[{"pt":[{"c":"ا","l":0},{"c":"س","l":1},{"c":"ت","l":2},{"c":"ا","l":5}]}],"pt75":[{"pt":[{"c":"ا","l":0},{"c":"ا","l":5}]}]}'),e.execArray=["cleanWord","removeDiacritics","cleanAlef","removeStopWords","normalizeHamzaAndAlef","removeStartWaw","removePre432","removeEndTaa","wordCheck"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHamzaAndAlef=function(){return e.word=e.word.replace("ؤ","ء"),e.word=e.word.replace("ئ","ء"),e.word=e.word.replace(/([\u0627])\1+/gi,"ا"),!1},e.removeEndTaa=function(){return!(e.word.length>2)||(e.word=e.word.replace(/[\u0627]$/,""),e.word=e.word.replace("ة",""),!1)},e.removeStartWaw=function(){return e.word.length>3&&"و"==e.word[0]&&"و"==e.word[1]&&(e.word=e.word.slice(1)),!1},e.removePre432=function(){var r=e.word;if(e.word.length>=7){var t=new RegExp("^("+e.pre.pre4.split(" ").join("|")+")");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=6){var c=new RegExp("^("+e.pre.pre3.split(" ").join("|")+")");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=5){var l=new RegExp("^("+e.pre.pre2.split(" ").join("|")+")");e.word=e.word.replace(l,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.patternCheck=function(r){for(var t=0;t3){var t=new RegExp("^("+e.pre.pre1.split(" ").join("|")+")");e.word=e.word.replace(t,"")}return r!=e.word&&(e.preRemoved=!0),!1},e.removeSuf1=function(){var r=e.word;if(0==e.sufRemoved&&e.word.length>3){var t=new RegExp("("+e.suf.suf1.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.removeSuf432=function(){var r=e.word;if(e.word.length>=6){var t=new RegExp("("+e.suf.suf4.split(" ").join("|")+")$");e.word=e.word.replace(t,"")}if(e.word==r&&e.word.length>=5){var c=new RegExp("("+e.suf.suf3.split(" ").join("|")+")$");e.word=e.word.replace(c,"")}if(e.word==r&&e.word.length>=4){var l=new RegExp("("+e.suf.suf2.split(" ").join("|")+")$");e.word=e.word.replace(l,"")}return r!=e.word&&(e.sufRemoved=!0),!1},e.wordCheck=function(){for(var r=(e.word,[e.removeSuf432,e.removeSuf1,e.removePre1]),t=0,c=!1;e.word.length>=7&&!e.result&&t=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.de.min.js b/assets/javascripts/lunr/min/lunr.de.min.js new file mode 100644 index 000000000..f3b5c108c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.de.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `German` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!v.eq_s(1,e)||(v.ket=v.cursor,!v.in_grouping(p,97,252)))&&(v.slice_from(r),v.cursor=n,!0)}function i(){for(var r,n,i,s,t=v.cursor;;)if(r=v.cursor,v.bra=r,v.eq_s(1,"ß"))v.ket=v.cursor,v.slice_from("ss");else{if(r>=v.limit)break;v.cursor=r+1}for(v.cursor=t;;)for(n=v.cursor;;){if(i=v.cursor,v.in_grouping(p,97,252)){if(s=v.cursor,v.bra=s,e("u","U",i))break;if(v.cursor=s,e("y","Y",i))break}if(i>=v.limit)return void(v.cursor=n);v.cursor=i+1}}function s(){for(;!v.in_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}for(;!v.out_grouping(p,97,252);){if(v.cursor>=v.limit)return!0;v.cursor++}return!1}function t(){m=v.limit,l=m;var e=v.cursor+3;0<=e&&e<=v.limit&&(d=e,s()||(m=v.cursor,m=v.limit)return;v.cursor++}}}function c(){return m<=v.cursor}function u(){return l<=v.cursor}function a(){var e,r,n,i,s=v.limit-v.cursor;if(v.ket=v.cursor,(e=v.find_among_b(w,7))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:v.slice_del(),v.ket=v.cursor,v.eq_s_b(1,"s")&&(v.bra=v.cursor,v.eq_s_b(3,"nis")&&v.slice_del());break;case 3:v.in_grouping_b(g,98,116)&&v.slice_del()}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(f,4))&&(v.bra=v.cursor,c()))switch(e){case 1:v.slice_del();break;case 2:if(v.in_grouping_b(k,98,116)){var t=v.cursor-3;v.limit_backward<=t&&t<=v.limit&&(v.cursor=t,v.slice_del())}}if(v.cursor=v.limit-s,v.ket=v.cursor,(e=v.find_among_b(_,8))&&(v.bra=v.cursor,u()))switch(e){case 1:v.slice_del(),v.ket=v.cursor,v.eq_s_b(2,"ig")&&(v.bra=v.cursor,r=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-r,u()&&v.slice_del()));break;case 2:n=v.limit-v.cursor,v.eq_s_b(1,"e")||(v.cursor=v.limit-n,v.slice_del());break;case 3:if(v.slice_del(),v.ket=v.cursor,i=v.limit-v.cursor,!v.eq_s_b(2,"er")&&(v.cursor=v.limit-i,!v.eq_s_b(2,"en")))break;v.bra=v.cursor,c()&&v.slice_del();break;case 4:v.slice_del(),v.ket=v.cursor,e=v.find_among_b(b,2),e&&(v.bra=v.cursor,u()&&1==e&&v.slice_del())}}var d,l,m,h=[new r("",-1,6),new r("U",0,2),new r("Y",0,1),new r("ä",0,3),new r("ö",0,4),new r("ü",0,5)],w=[new r("e",-1,2),new r("em",-1,1),new r("en",-1,2),new r("ern",-1,1),new r("er",-1,1),new r("s",-1,3),new r("es",5,2)],f=[new r("en",-1,1),new r("er",-1,1),new r("st",-1,2),new r("est",2,1)],b=[new r("ig",-1,1),new r("lich",-1,1)],_=[new r("end",-1,1),new r("ig",-1,2),new r("ung",-1,1),new r("lich",-1,3),new r("isch",-1,2),new r("ik",-1,2),new r("heit",-1,3),new r("keit",-1,4)],p=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],g=[117,30,5],k=[117,30,4],v=new n;this.setCurrent=function(e){v.setCurrent(e)},this.getCurrent=function(){return v.getCurrent()},this.stem=function(){var e=v.cursor;return i(),v.cursor=e,t(),v.limit_backward=e,v.cursor=v.limit,a(),v.cursor=v.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.du.min.js b/assets/javascripts/lunr/min/lunr.du.min.js new file mode 100644 index 000000000..49a0f3f0a --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.du.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Dutch` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e,r,i,o=C.cursor;;){if(C.bra=C.cursor,e=C.find_among(b,11))switch(C.ket=C.cursor,e){case 1:C.slice_from("a");continue;case 2:C.slice_from("e");continue;case 3:C.slice_from("i");continue;case 4:C.slice_from("o");continue;case 5:C.slice_from("u");continue;case 6:if(C.cursor>=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(r=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=r);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=r;else if(n(r))break}else if(n(r))break}function n(e){return C.cursor=e,e>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,f=_,t()||(_=C.cursor,_<3&&(_=3),t()||(f=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var e;;)if(C.bra=C.cursor,e=C.find_among(p,3))switch(C.ket=C.cursor,e){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return f<=C.cursor}function a(){var e=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-e,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var e;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.slice_del(),w=!0,a())))}function m(){var e;u()&&(e=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-e,C.eq_s_b(3,"gem")||(C.cursor=C.limit-e,C.slice_del(),a())))}function d(){var e,r,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,e=C.find_among_b(h,5))switch(C.bra=C.cursor,e){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(z,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(r=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-r,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,e=C.find_among_b(k,6))switch(C.bra=C.cursor,e){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(j,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var f,_,w,b=[new r("",-1,6),new r("á",0,1),new r("ä",0,1),new r("é",0,2),new r("ë",0,2),new r("í",0,3),new r("ï",0,3),new r("ó",0,4),new r("ö",0,4),new r("ú",0,5),new r("ü",0,5)],p=[new r("",-1,3),new r("I",0,2),new r("Y",0,1)],g=[new r("dd",-1,-1),new r("kk",-1,-1),new r("tt",-1,-1)],h=[new r("ene",-1,2),new r("se",-1,3),new r("en",-1,2),new r("heden",2,1),new r("s",-1,3)],k=[new r("end",-1,1),new r("ig",-1,2),new r("ing",-1,1),new r("lijk",-1,3),new r("baar",-1,4),new r("bar",-1,5)],v=[new r("aa",-1,-1),new r("ee",-1,-1),new r("oo",-1,-1),new r("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(e){C.setCurrent(e)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var r=C.cursor;return e(),C.cursor=r,o(),C.limit_backward=r,C.cursor=C.limit,d(),C.cursor=C.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.es.min.js b/assets/javascripts/lunr/min/lunr.es.min.js new file mode 100644 index 000000000..2989d3426 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.es.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Spanish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,"trimmer-es"),e.es.stemmer=function(){var s=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(){if(A.out_grouping(x,97,252)){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}return!0}function n(){if(A.in_grouping(x,97,252)){var s=A.cursor;if(e()){if(A.cursor=s,!A.in_grouping(x,97,252))return!0;for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!0;A.cursor++}}return!1}return!0}function i(){var s,r=A.cursor;if(n()){if(A.cursor=r,!A.out_grouping(x,97,252))return;if(s=A.cursor,e()){if(A.cursor=s,!A.in_grouping(x,97,252)||A.cursor>=A.limit)return;A.cursor++}}g=A.cursor}function a(){for(;!A.in_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}for(;!A.out_grouping(x,97,252);){if(A.cursor>=A.limit)return!1;A.cursor++}return!0}function t(){var e=A.cursor;g=A.limit,p=g,v=g,i(),A.cursor=e,a()&&(p=A.cursor,a()&&(v=A.cursor))}function o(){for(var e;;){if(A.bra=A.cursor,e=A.find_among(k,6))switch(A.ket=A.cursor,e){case 1:A.slice_from("a");continue;case 2:A.slice_from("e");continue;case 3:A.slice_from("i");continue;case 4:A.slice_from("o");continue;case 5:A.slice_from("u");continue;case 6:if(A.cursor>=A.limit)break;A.cursor++;continue}break}}function u(){return g<=A.cursor}function w(){return p<=A.cursor}function c(){return v<=A.cursor}function m(){var e;if(A.ket=A.cursor,A.find_among_b(y,13)&&(A.bra=A.cursor,(e=A.find_among_b(q,11))&&u()))switch(e){case 1:A.bra=A.cursor,A.slice_from("iendo");break;case 2:A.bra=A.cursor,A.slice_from("ando");break;case 3:A.bra=A.cursor,A.slice_from("ar");break;case 4:A.bra=A.cursor,A.slice_from("er");break;case 5:A.bra=A.cursor,A.slice_from("ir");break;case 6:A.slice_del();break;case 7:A.eq_s_b(1,"u")&&A.slice_del()}}function l(e,s){if(!c())return!0;A.slice_del(),A.ket=A.cursor;var r=A.find_among_b(e,s);return r&&(A.bra=A.cursor,1==r&&c()&&A.slice_del()),!1}function d(e){return!c()||(A.slice_del(),A.ket=A.cursor,A.eq_s_b(2,e)&&(A.bra=A.cursor,c()&&A.slice_del()),!1)}function b(){var e;if(A.ket=A.cursor,e=A.find_among_b(S,46)){switch(A.bra=A.cursor,e){case 1:if(!c())return!1;A.slice_del();break;case 2:if(d("ic"))return!1;break;case 3:if(!c())return!1;A.slice_from("log");break;case 4:if(!c())return!1;A.slice_from("u");break;case 5:if(!c())return!1;A.slice_from("ente");break;case 6:if(!w())return!1;A.slice_del(),A.ket=A.cursor,e=A.find_among_b(C,4),e&&(A.bra=A.cursor,c()&&(A.slice_del(),1==e&&(A.ket=A.cursor,A.eq_s_b(2,"at")&&(A.bra=A.cursor,c()&&A.slice_del()))));break;case 7:if(l(P,3))return!1;break;case 8:if(l(F,3))return!1;break;case 9:if(d("at"))return!1}return!0}return!1}function f(){var e,s;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(W,12),A.limit_backward=s,e)){if(A.bra=A.cursor,1==e){if(!A.eq_s_b(1,"u"))return!1;A.slice_del()}return!0}return!1}function _(){var e,s,r,n;if(A.cursor>=g&&(s=A.limit_backward,A.limit_backward=g,A.ket=A.cursor,e=A.find_among_b(L,96),A.limit_backward=s,e))switch(A.bra=A.cursor,e){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"u")?(n=A.limit-A.cursor,A.eq_s_b(1,"g")?A.cursor=A.limit-n:A.cursor=A.limit-r):A.cursor=A.limit-r,A.bra=A.cursor;case 2:A.slice_del()}}function h(){var e,s;if(A.ket=A.cursor,e=A.find_among_b(z,8))switch(A.bra=A.cursor,e){case 1:u()&&A.slice_del();break;case 2:u()&&(A.slice_del(),A.ket=A.cursor,A.eq_s_b(1,"u")&&(A.bra=A.cursor,s=A.limit-A.cursor,A.eq_s_b(1,"g")&&(A.cursor=A.limit-s,u()&&A.slice_del())))}}var v,p,g,k=[new s("",-1,6),new s("á",0,1),new s("é",0,2),new s("í",0,3),new s("ó",0,4),new s("ú",0,5)],y=[new s("la",-1,-1),new s("sela",0,-1),new s("le",-1,-1),new s("me",-1,-1),new s("se",-1,-1),new s("lo",-1,-1),new s("selo",5,-1),new s("las",-1,-1),new s("selas",7,-1),new s("les",-1,-1),new s("los",-1,-1),new s("selos",10,-1),new s("nos",-1,-1)],q=[new s("ando",-1,6),new s("iendo",-1,6),new s("yendo",-1,7),new s("ándo",-1,2),new s("iéndo",-1,1),new s("ar",-1,6),new s("er",-1,6),new s("ir",-1,6),new s("ár",-1,3),new s("ér",-1,4),new s("ír",-1,5)],C=[new s("ic",-1,-1),new s("ad",-1,-1),new s("os",-1,-1),new s("iv",-1,1)],P=[new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,1)],F=[new s("ic",-1,1),new s("abil",-1,1),new s("iv",-1,1)],S=[new s("ica",-1,1),new s("ancia",-1,2),new s("encia",-1,5),new s("adora",-1,2),new s("osa",-1,1),new s("ista",-1,1),new s("iva",-1,9),new s("anza",-1,1),new s("logía",-1,3),new s("idad",-1,8),new s("able",-1,1),new s("ible",-1,1),new s("ante",-1,2),new s("mente",-1,7),new s("amente",13,6),new s("ación",-1,2),new s("ución",-1,4),new s("ico",-1,1),new s("ismo",-1,1),new s("oso",-1,1),new s("amiento",-1,1),new s("imiento",-1,1),new s("ivo",-1,9),new s("ador",-1,2),new s("icas",-1,1),new s("ancias",-1,2),new s("encias",-1,5),new s("adoras",-1,2),new s("osas",-1,1),new s("istas",-1,1),new s("ivas",-1,9),new s("anzas",-1,1),new s("logías",-1,3),new s("idades",-1,8),new s("ables",-1,1),new s("ibles",-1,1),new s("aciones",-1,2),new s("uciones",-1,4),new s("adores",-1,2),new s("antes",-1,2),new s("icos",-1,1),new s("ismos",-1,1),new s("osos",-1,1),new s("amientos",-1,1),new s("imientos",-1,1),new s("ivos",-1,9)],W=[new s("ya",-1,1),new s("ye",-1,1),new s("yan",-1,1),new s("yen",-1,1),new s("yeron",-1,1),new s("yendo",-1,1),new s("yo",-1,1),new s("yas",-1,1),new s("yes",-1,1),new s("yais",-1,1),new s("yamos",-1,1),new s("yó",-1,1)],L=[new s("aba",-1,2),new s("ada",-1,2),new s("ida",-1,2),new s("ara",-1,2),new s("iera",-1,2),new s("ía",-1,2),new s("aría",5,2),new s("ería",5,2),new s("iría",5,2),new s("ad",-1,2),new s("ed",-1,2),new s("id",-1,2),new s("ase",-1,2),new s("iese",-1,2),new s("aste",-1,2),new s("iste",-1,2),new s("an",-1,2),new s("aban",16,2),new s("aran",16,2),new s("ieran",16,2),new s("ían",16,2),new s("arían",20,2),new s("erían",20,2),new s("irían",20,2),new s("en",-1,1),new s("asen",24,2),new s("iesen",24,2),new s("aron",-1,2),new s("ieron",-1,2),new s("arán",-1,2),new s("erán",-1,2),new s("irán",-1,2),new s("ado",-1,2),new s("ido",-1,2),new s("ando",-1,2),new s("iendo",-1,2),new s("ar",-1,2),new s("er",-1,2),new s("ir",-1,2),new s("as",-1,2),new s("abas",39,2),new s("adas",39,2),new s("idas",39,2),new s("aras",39,2),new s("ieras",39,2),new s("ías",39,2),new s("arías",45,2),new s("erías",45,2),new s("irías",45,2),new s("es",-1,1),new s("ases",49,2),new s("ieses",49,2),new s("abais",-1,2),new s("arais",-1,2),new s("ierais",-1,2),new s("íais",-1,2),new s("aríais",55,2),new s("eríais",55,2),new s("iríais",55,2),new s("aseis",-1,2),new s("ieseis",-1,2),new s("asteis",-1,2),new s("isteis",-1,2),new s("áis",-1,2),new s("éis",-1,1),new s("aréis",64,2),new s("eréis",64,2),new s("iréis",64,2),new s("ados",-1,2),new s("idos",-1,2),new s("amos",-1,2),new s("ábamos",70,2),new s("áramos",70,2),new s("iéramos",70,2),new s("íamos",70,2),new s("aríamos",74,2),new s("eríamos",74,2),new s("iríamos",74,2),new s("emos",-1,1),new s("aremos",78,2),new s("eremos",78,2),new s("iremos",78,2),new s("ásemos",78,2),new s("iésemos",78,2),new s("imos",-1,2),new s("arás",-1,2),new s("erás",-1,2),new s("irás",-1,2),new s("ís",-1,2),new s("ará",-1,2),new s("erá",-1,2),new s("irá",-1,2),new s("aré",-1,2),new s("eré",-1,2),new s("iré",-1,2),new s("ió",-1,2)],z=[new s("a",-1,1),new s("e",-1,2),new s("o",-1,1),new s("os",-1,1),new s("á",-1,1),new s("é",-1,2),new s("í",-1,1),new s("ó",-1,1)],x=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],A=new r;this.setCurrent=function(e){A.setCurrent(e)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return t(),A.limit_backward=e,A.cursor=A.limit,m(),A.cursor=A.limit,b()||(A.cursor=A.limit,f()||(A.cursor=A.limit,_())),A.cursor=A.limit,h(),A.cursor=A.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fi.min.js b/assets/javascripts/lunr/min/lunr.fi.min.js new file mode 100644 index 000000000..29f5dfcea --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fi.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Finnish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=function(){var e=i.stemmerSupport.Among,r=i.stemmerSupport.SnowballProgram,n=new function(){function i(){f=A.limit,d=f,n()||(f=A.cursor,n()||(d=A.cursor))}function n(){for(var i;;){if(i=A.cursor,A.in_grouping(W,97,246))break;if(A.cursor=i,i>=A.limit)return!0;A.cursor++}for(A.cursor=i;!A.out_grouping(W,97,246);){if(A.cursor>=A.limit)return!0;A.cursor++}return!1}function t(){return d<=A.cursor}function s(){var i,e;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(h,10)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.in_grouping_b(x,97,246))return;break;case 2:if(!t())return}A.slice_del()}else A.limit_backward=e}function o(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(v,9))switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:r=A.limit-A.cursor,A.eq_s_b(1,"k")||(A.cursor=A.limit-r,A.slice_del());break;case 2:A.slice_del(),A.ket=A.cursor,A.eq_s_b(3,"kse")&&(A.bra=A.cursor,A.slice_from("ksi"));break;case 3:A.slice_del();break;case 4:A.find_among_b(p,6)&&A.slice_del();break;case 5:A.find_among_b(g,6)&&A.slice_del();break;case 6:A.find_among_b(j,2)&&A.slice_del()}else A.limit_backward=e}function l(){return A.find_among_b(q,7)}function a(){return A.eq_s_b(1,"i")&&A.in_grouping_b(L,97,246)}function u(){var i,e,r;if(A.cursor>=f)if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,i=A.find_among_b(C,30)){switch(A.bra=A.cursor,A.limit_backward=e,i){case 1:if(!A.eq_s_b(1,"a"))return;break;case 2:case 9:if(!A.eq_s_b(1,"e"))return;break;case 3:if(!A.eq_s_b(1,"i"))return;break;case 4:if(!A.eq_s_b(1,"o"))return;break;case 5:if(!A.eq_s_b(1,"ä"))return;break;case 6:if(!A.eq_s_b(1,"ö"))return;break;case 7:if(r=A.limit-A.cursor,!l()&&(A.cursor=A.limit-r,!A.eq_s_b(2,"ie"))){A.cursor=A.limit-r;break}if(A.cursor=A.limit-r,A.cursor<=A.limit_backward){A.cursor=A.limit-r;break}A.cursor--,A.bra=A.cursor;break;case 8:if(!A.in_grouping_b(W,97,246)||!A.out_grouping_b(W,97,246))return}A.slice_del(),k=!0}else A.limit_backward=e}function c(){var i,e,r;if(A.cursor>=d)if(e=A.limit_backward,A.limit_backward=d,A.ket=A.cursor,i=A.find_among_b(P,14)){if(A.bra=A.cursor,A.limit_backward=e,1==i){if(r=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-r}A.slice_del()}else A.limit_backward=e}function m(){var i;A.cursor>=f&&(i=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.find_among_b(F,2)?(A.bra=A.cursor,A.limit_backward=i,A.slice_del()):A.limit_backward=i)}function w(){var i,e,r,n,t,s;if(A.cursor>=f){if(e=A.limit_backward,A.limit_backward=f,A.ket=A.cursor,A.eq_s_b(1,"t")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.in_grouping_b(W,97,246)&&(A.cursor=A.limit-r,A.slice_del(),A.limit_backward=e,n=A.limit-A.cursor,A.cursor>=d&&(A.cursor=d,t=A.limit_backward,A.limit_backward=A.cursor,A.cursor=A.limit-n,A.ket=A.cursor,i=A.find_among_b(S,2))))){if(A.bra=A.cursor,A.limit_backward=t,1==i){if(s=A.limit-A.cursor,A.eq_s_b(2,"po"))return;A.cursor=A.limit-s}return void A.slice_del()}A.limit_backward=e}}function _(){var i,e,r,n;if(A.cursor>=f){for(i=A.limit_backward,A.limit_backward=f,e=A.limit-A.cursor,l()&&(A.cursor=A.limit-e,A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.in_grouping_b(y,97,228)&&(A.bra=A.cursor,A.out_grouping_b(W,97,246)&&A.slice_del()),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"j")&&(A.bra=A.cursor,r=A.limit-A.cursor,A.eq_s_b(1,"o")?A.slice_del():(A.cursor=A.limit-r,A.eq_s_b(1,"u")&&A.slice_del())),A.cursor=A.limit-e,A.ket=A.cursor,A.eq_s_b(1,"o")&&(A.bra=A.cursor,A.eq_s_b(1,"j")&&A.slice_del()),A.cursor=A.limit-e,A.limit_backward=i;;){if(n=A.limit-A.cursor,A.out_grouping_b(W,97,246)){A.cursor=A.limit-n;break}if(A.cursor=A.limit-n,A.cursor<=A.limit_backward)return;A.cursor--}A.ket=A.cursor,A.cursor>A.limit_backward&&(A.cursor--,A.bra=A.cursor,b=A.slice_to(),A.eq_v_b(b)&&A.slice_del())}}var k,b,d,f,h=[new e("pa",-1,1),new e("sti",-1,2),new e("kaan",-1,1),new e("han",-1,1),new e("kin",-1,1),new e("hän",-1,1),new e("kään",-1,1),new e("ko",-1,1),new e("pä",-1,1),new e("kö",-1,1)],p=[new e("lla",-1,-1),new e("na",-1,-1),new e("ssa",-1,-1),new e("ta",-1,-1),new e("lta",3,-1),new e("sta",3,-1)],g=[new e("llä",-1,-1),new e("nä",-1,-1),new e("ssä",-1,-1),new e("tä",-1,-1),new e("ltä",3,-1),new e("stä",3,-1)],j=[new e("lle",-1,-1),new e("ine",-1,-1)],v=[new e("nsa",-1,3),new e("mme",-1,3),new e("nne",-1,3),new e("ni",-1,2),new e("si",-1,1),new e("an",-1,4),new e("en",-1,6),new e("än",-1,5),new e("nsä",-1,3)],q=[new e("aa",-1,-1),new e("ee",-1,-1),new e("ii",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1),new e("ää",-1,-1),new e("öö",-1,-1)],C=[new e("a",-1,8),new e("lla",0,-1),new e("na",0,-1),new e("ssa",0,-1),new e("ta",0,-1),new e("lta",4,-1),new e("sta",4,-1),new e("tta",4,9),new e("lle",-1,-1),new e("ine",-1,-1),new e("ksi",-1,-1),new e("n",-1,7),new e("han",11,1),new e("den",11,-1,a),new e("seen",11,-1,l),new e("hen",11,2),new e("tten",11,-1,a),new e("hin",11,3),new e("siin",11,-1,a),new e("hon",11,4),new e("hän",11,5),new e("hön",11,6),new e("ä",-1,8),new e("llä",22,-1),new e("nä",22,-1),new e("ssä",22,-1),new e("tä",22,-1),new e("ltä",26,-1),new e("stä",26,-1),new e("ttä",26,9)],P=[new e("eja",-1,-1),new e("mma",-1,1),new e("imma",1,-1),new e("mpa",-1,1),new e("impa",3,-1),new e("mmi",-1,1),new e("immi",5,-1),new e("mpi",-1,1),new e("impi",7,-1),new e("ejä",-1,-1),new e("mmä",-1,1),new e("immä",10,-1),new e("mpä",-1,1),new e("impä",12,-1)],F=[new e("i",-1,-1),new e("j",-1,-1)],S=[new e("mma",-1,1),new e("imma",0,-1)],y=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],W=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],x=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],A=new r;this.setCurrent=function(i){A.setCurrent(i)},this.getCurrent=function(){return A.getCurrent()},this.stem=function(){var e=A.cursor;return i(),k=!1,A.limit_backward=e,A.cursor=A.limit,s(),A.cursor=A.limit,o(),A.cursor=A.limit,u(),A.cursor=A.limit,c(),A.cursor=A.limit,k?(m(),A.cursor=A.limit):(A.cursor=A.limit,w(),A.cursor=A.limit),_(),!0}};return function(i){return"function"==typeof i.update?i.update(function(i){return n.setCurrent(i),n.stem(),n.getCurrent()}):(n.setCurrent(i),n.stem(),n.getCurrent())}}(),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.fr.min.js b/assets/javascripts/lunr/min/lunr.fr.min.js new file mode 100644 index 000000000..68cd0094a --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.fr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `French` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,s){return!(!W.eq_s(1,e)||(W.ket=W.cursor,!W.in_grouping(F,97,251)))&&(W.slice_from(r),W.cursor=s,!0)}function i(e,r,s){return!!W.eq_s(1,e)&&(W.ket=W.cursor,W.slice_from(r),W.cursor=s,!0)}function n(){for(var r,s;;){if(r=W.cursor,W.in_grouping(F,97,251)){if(W.bra=W.cursor,s=W.cursor,e("u","U",r))continue;if(W.cursor=s,e("i","I",r))continue;if(W.cursor=s,i("y","Y",r))continue}if(W.cursor=r,W.bra=r,!e("y","Y",r)){if(W.cursor=r,W.eq_s(1,"q")&&(W.bra=W.cursor,i("u","U",r)))continue;if(W.cursor=r,r>=W.limit)return;W.cursor++}}}function t(){for(;!W.in_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}for(;!W.out_grouping(F,97,251);){if(W.cursor>=W.limit)return!0;W.cursor++}return!1}function u(){var e=W.cursor;if(q=W.limit,g=q,p=q,W.in_grouping(F,97,251)&&W.in_grouping(F,97,251)&&W.cursor=W.limit){W.cursor=q;break}W.cursor++}while(!W.in_grouping(F,97,251))}q=W.cursor,W.cursor=e,t()||(g=W.cursor,t()||(p=W.cursor))}function o(){for(var e,r;;){if(r=W.cursor,W.bra=r,!(e=W.find_among(h,4)))break;switch(W.ket=W.cursor,e){case 1:W.slice_from("i");break;case 2:W.slice_from("u");break;case 3:W.slice_from("y");break;case 4:if(W.cursor>=W.limit)return;W.cursor++}}}function c(){return q<=W.cursor}function a(){return g<=W.cursor}function l(){return p<=W.cursor}function w(){var e,r;if(W.ket=W.cursor,e=W.find_among_b(C,43)){switch(W.bra=W.cursor,e){case 1:if(!l())return!1;W.slice_del();break;case 2:if(!l())return!1;W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")&&(W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU"));break;case 3:if(!l())return!1;W.slice_from("log");break;case 4:if(!l())return!1;W.slice_from("u");break;case 5:if(!l())return!1;W.slice_from("ent");break;case 6:if(!c())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(z,6))switch(W.bra=W.cursor,e){case 1:l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&W.slice_del()));break;case 2:l()?W.slice_del():a()&&W.slice_from("eux");break;case 3:l()&&W.slice_del();break;case 4:c()&&W.slice_from("i")}break;case 7:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,e=W.find_among_b(y,3))switch(W.bra=W.cursor,e){case 1:l()?W.slice_del():W.slice_from("abl");break;case 2:l()?W.slice_del():W.slice_from("iqU");break;case 3:l()&&W.slice_del()}break;case 8:if(!l())return!1;if(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"at")&&(W.bra=W.cursor,l()&&(W.slice_del(),W.ket=W.cursor,W.eq_s_b(2,"ic")))){W.bra=W.cursor,l()?W.slice_del():W.slice_from("iqU");break}break;case 9:W.slice_from("eau");break;case 10:if(!a())return!1;W.slice_from("al");break;case 11:if(l())W.slice_del();else{if(!a())return!1;W.slice_from("eux")}break;case 12:if(!a()||!W.out_grouping_b(F,97,251))return!1;W.slice_del();break;case 13:return c()&&W.slice_from("ant"),!1;case 14:return c()&&W.slice_from("ent"),!1;case 15:return r=W.limit-W.cursor,W.in_grouping_b(F,97,251)&&c()&&(W.cursor=W.limit-r,W.slice_del()),!1}return!0}return!1}function f(){var e,r;if(W.cursor=q){if(s=W.limit_backward,W.limit_backward=q,W.ket=W.cursor,e=W.find_among_b(P,7))switch(W.bra=W.cursor,e){case 1:if(l()){if(i=W.limit-W.cursor,!W.eq_s_b(1,"s")&&(W.cursor=W.limit-i,!W.eq_s_b(1,"t")))break;W.slice_del()}break;case 2:W.slice_from("i");break;case 3:W.slice_del();break;case 4:W.eq_s_b(2,"gu")&&W.slice_del()}W.limit_backward=s}}function b(){var e=W.limit-W.cursor;W.find_among_b(U,5)&&(W.cursor=W.limit-e,W.ket=W.cursor,W.cursor>W.limit_backward&&(W.cursor--,W.bra=W.cursor,W.slice_del()))}function d(){for(var e,r=1;W.out_grouping_b(F,97,251);)r--;if(r<=0){if(W.ket=W.cursor,e=W.limit-W.cursor,!W.eq_s_b(1,"é")&&(W.cursor=W.limit-e,!W.eq_s_b(1,"è")))return;W.bra=W.cursor,W.slice_from("e")}}function k(){if(!w()&&(W.cursor=W.limit,!f()&&(W.cursor=W.limit,!m())))return W.cursor=W.limit,void _();W.cursor=W.limit,W.ket=W.cursor,W.eq_s_b(1,"Y")?(W.bra=W.cursor,W.slice_from("i")):(W.cursor=W.limit,W.eq_s_b(1,"ç")&&(W.bra=W.cursor,W.slice_from("c")))}var p,g,q,v=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],h=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],z=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],y=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],C=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],x=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],I=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],P=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],U=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],F=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],S=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],W=new s;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){var e=W.cursor;return n(),W.cursor=e,u(),W.limit_backward=e,W.cursor=W.limit,k(),W.cursor=W.limit,b(),W.cursor=W.limit,d(),W.cursor=W.limit_backward,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hi.min.js b/assets/javascripts/lunr/min/lunr.hi.min.js new file mode 100644 index 000000000..7dbc41402 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hi=function(){this.pipeline.reset(),this.pipeline.add(e.hi.trimmer,e.hi.stopWordFilter,e.hi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hi.stemmer))},e.hi.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿa-zA-Za-zA-Z0-90-9",e.hi.trimmer=e.trimmerSupport.generateTrimmer(e.hi.wordCharacters),e.Pipeline.registerFunction(e.hi.trimmer,"trimmer-hi"),e.hi.stopWordFilter=e.generateStopWordFilter("अत अपना अपनी अपने अभी अंदर आदि आप इत्यादि इन इनका इन्हीं इन्हें इन्हों इस इसका इसकी इसके इसमें इसी इसे उन उनका उनकी उनके उनको उन्हीं उन्हें उन्हों उस उसके उसी उसे एक एवं एस ऐसे और कई कर करता करते करना करने करें कहते कहा का काफ़ी कि कितना किन्हें किन्हों किया किर किस किसी किसे की कुछ कुल के को कोई कौन कौनसा गया घर जब जहाँ जा जितना जिन जिन्हें जिन्हों जिस जिसे जीधर जैसा जैसे जो तक तब तरह तिन तिन्हें तिन्हों तिस तिसे तो था थी थे दबारा दिया दुसरा दूसरे दो द्वारा न नके नहीं ना निहायत नीचे ने पर पहले पूरा पे फिर बनी बही बहुत बाद बाला बिलकुल भी भीतर मगर मानो मे में यदि यह यहाँ यही या यिह ये रखें रहा रहे ऱ्वासा लिए लिये लेकिन व वग़ैरह वर्ग वह वहाँ वहीं वाले वुह वे वो सकता सकते सबसे सभी साथ साबुत साभ सारा से सो संग ही हुआ हुई हुए है हैं हो होता होती होते होना होने".split(" ")),e.hi.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.hi.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var t=i.toString().toLowerCase().replace(/^\s+/,"");return r.cut(t).split("|")},e.Pipeline.registerFunction(e.hi.stemmer,"stemmer-hi"),e.Pipeline.registerFunction(e.hi.stopWordFilter,"stopWordFilter-hi")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.hu.min.js b/assets/javascripts/lunr/min/lunr.hu.min.js new file mode 100644 index 000000000..ed9d909f7 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.hu.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Hungarian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,n=L.cursor;if(d=L.limit,L.in_grouping(W,97,252))for(;;){if(e=L.cursor,L.out_grouping(W,97,252))return L.cursor=e,L.find_among(g,8)||(L.cursor=e,e=L.limit)return void(d=e);L.cursor++}if(L.cursor=n,L.out_grouping(W,97,252)){for(;!L.in_grouping(W,97,252);){if(L.cursor>=L.limit)return;L.cursor++}d=L.cursor}}function i(){return d<=L.cursor}function a(){var e;if(L.ket=L.cursor,(e=L.find_among_b(h,2))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e")}}function t(){var e=L.limit-L.cursor;return!!L.find_among_b(p,23)&&(L.cursor=L.limit-e,!0)}function s(){if(L.cursor>L.limit_backward){L.cursor--,L.ket=L.cursor;var e=L.cursor-1;L.limit_backward<=e&&e<=L.limit&&(L.cursor=e,L.bra=e,L.slice_del())}}function c(){var e;if(L.ket=L.cursor,(e=L.find_among_b(_,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function o(){L.ket=L.cursor,L.find_among_b(v,44)&&(L.bra=L.cursor,i()&&(L.slice_del(),a()))}function w(){var e;if(L.ket=L.cursor,(e=L.find_among_b(z,3))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("e");break;case 2:case 3:L.slice_from("a")}}function l(){var e;if(L.ket=L.cursor,(e=L.find_among_b(y,6))&&(L.bra=L.cursor,i()))switch(e){case 1:case 2:L.slice_del();break;case 3:L.slice_from("a");break;case 4:L.slice_from("e")}}function u(){var e;if(L.ket=L.cursor,(e=L.find_among_b(j,2))&&(L.bra=L.cursor,i())){if((1==e||2==e)&&!t())return;L.slice_del(),s()}}function m(){var e;if(L.ket=L.cursor,(e=L.find_among_b(C,7))&&(L.bra=L.cursor,i()))switch(e){case 1:L.slice_from("a");break;case 2:L.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:L.slice_del()}}function k(){var e;if(L.ket=L.cursor,(e=L.find_among_b(P,12))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 9:L.slice_del();break;case 2:case 5:case 8:L.slice_from("e");break;case 3:case 6:L.slice_from("a")}}function f(){var e;if(L.ket=L.cursor,(e=L.find_among_b(F,31))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:L.slice_del();break;case 2:case 5:case 10:case 14:case 19:L.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:L.slice_from("e")}}function b(){var e;if(L.ket=L.cursor,(e=L.find_among_b(S,42))&&(L.bra=L.cursor,i()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:L.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:L.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:L.slice_from("e")}}var d,g=[new n("cs",-1,-1),new n("dzs",-1,-1),new n("gy",-1,-1),new n("ly",-1,-1),new n("ny",-1,-1),new n("sz",-1,-1),new n("ty",-1,-1),new n("zs",-1,-1)],h=[new n("á",-1,1),new n("é",-1,2)],p=[new n("bb",-1,-1),new n("cc",-1,-1),new n("dd",-1,-1),new n("ff",-1,-1),new n("gg",-1,-1),new n("jj",-1,-1),new n("kk",-1,-1),new n("ll",-1,-1),new n("mm",-1,-1),new n("nn",-1,-1),new n("pp",-1,-1),new n("rr",-1,-1),new n("ccs",-1,-1),new n("ss",-1,-1),new n("zzs",-1,-1),new n("tt",-1,-1),new n("vv",-1,-1),new n("ggy",-1,-1),new n("lly",-1,-1),new n("nny",-1,-1),new n("tty",-1,-1),new n("ssz",-1,-1),new n("zz",-1,-1)],_=[new n("al",-1,1),new n("el",-1,2)],v=[new n("ba",-1,-1),new n("ra",-1,-1),new n("be",-1,-1),new n("re",-1,-1),new n("ig",-1,-1),new n("nak",-1,-1),new n("nek",-1,-1),new n("val",-1,-1),new n("vel",-1,-1),new n("ul",-1,-1),new n("nál",-1,-1),new n("nél",-1,-1),new n("ból",-1,-1),new n("ról",-1,-1),new n("tól",-1,-1),new n("bõl",-1,-1),new n("rõl",-1,-1),new n("tõl",-1,-1),new n("ül",-1,-1),new n("n",-1,-1),new n("an",19,-1),new n("ban",20,-1),new n("en",19,-1),new n("ben",22,-1),new n("képpen",22,-1),new n("on",19,-1),new n("ön",19,-1),new n("képp",-1,-1),new n("kor",-1,-1),new n("t",-1,-1),new n("at",29,-1),new n("et",29,-1),new n("ként",29,-1),new n("anként",32,-1),new n("enként",32,-1),new n("onként",32,-1),new n("ot",29,-1),new n("ért",29,-1),new n("öt",29,-1),new n("hez",-1,-1),new n("hoz",-1,-1),new n("höz",-1,-1),new n("vá",-1,-1),new n("vé",-1,-1)],z=[new n("án",-1,2),new n("én",-1,1),new n("ánként",-1,3)],y=[new n("stul",-1,2),new n("astul",0,1),new n("ástul",0,3),new n("stül",-1,2),new n("estül",3,1),new n("éstül",3,4)],j=[new n("á",-1,1),new n("é",-1,2)],C=[new n("k",-1,7),new n("ak",0,4),new n("ek",0,6),new n("ok",0,5),new n("ák",0,1),new n("ék",0,2),new n("ök",0,3)],P=[new n("éi",-1,7),new n("áéi",0,6),new n("ééi",0,5),new n("é",-1,9),new n("ké",3,4),new n("aké",4,1),new n("eké",4,1),new n("oké",4,1),new n("áké",4,3),new n("éké",4,2),new n("öké",4,1),new n("éé",3,8)],F=[new n("a",-1,18),new n("ja",0,17),new n("d",-1,16),new n("ad",2,13),new n("ed",2,13),new n("od",2,13),new n("ád",2,14),new n("éd",2,15),new n("öd",2,13),new n("e",-1,18),new n("je",9,17),new n("nk",-1,4),new n("unk",11,1),new n("ánk",11,2),new n("énk",11,3),new n("ünk",11,1),new n("uk",-1,8),new n("juk",16,7),new n("ájuk",17,5),new n("ük",-1,8),new n("jük",19,7),new n("éjük",20,6),new n("m",-1,12),new n("am",22,9),new n("em",22,9),new n("om",22,9),new n("ám",22,10),new n("ém",22,11),new n("o",-1,18),new n("á",-1,19),new n("é",-1,20)],S=[new n("id",-1,10),new n("aid",0,9),new n("jaid",1,6),new n("eid",0,9),new n("jeid",3,6),new n("áid",0,7),new n("éid",0,8),new n("i",-1,15),new n("ai",7,14),new n("jai",8,11),new n("ei",7,14),new n("jei",10,11),new n("ái",7,12),new n("éi",7,13),new n("itek",-1,24),new n("eitek",14,21),new n("jeitek",15,20),new n("éitek",14,23),new n("ik",-1,29),new n("aik",18,26),new n("jaik",19,25),new n("eik",18,26),new n("jeik",21,25),new n("áik",18,27),new n("éik",18,28),new n("ink",-1,20),new n("aink",25,17),new n("jaink",26,16),new n("eink",25,17),new n("jeink",28,16),new n("áink",25,18),new n("éink",25,19),new n("aitok",-1,21),new n("jaitok",32,20),new n("áitok",-1,22),new n("im",-1,5),new n("aim",35,4),new n("jaim",36,1),new n("eim",35,4),new n("jeim",38,1),new n("áim",35,2),new n("éim",35,3)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var n=L.cursor;return e(),L.limit_backward=n,L.cursor=L.limit,c(),L.cursor=L.limit,o(),L.cursor=L.limit,w(),L.cursor=L.limit,l(),L.cursor=L.limit,u(),L.cursor=L.limit,k(),L.cursor=L.limit,f(),L.cursor=L.limit,b(),L.cursor=L.limit,m(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.it.min.js b/assets/javascripts/lunr/min/lunr.it.min.js new file mode 100644 index 000000000..344b6a3c0 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.it.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Italian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(e,r,n){return!(!x.eq_s(1,e)||(x.ket=x.cursor,!x.in_grouping(L,97,249)))&&(x.slice_from(r),x.cursor=n,!0)}function i(){for(var r,n,i,o,t=x.cursor;;){if(x.bra=x.cursor,r=x.find_among(h,7))switch(x.ket=x.cursor,r){case 1:x.slice_from("à");continue;case 2:x.slice_from("è");continue;case 3:x.slice_from("ì");continue;case 4:x.slice_from("ò");continue;case 5:x.slice_from("ù");continue;case 6:x.slice_from("qU");continue;case 7:if(x.cursor>=x.limit)break;x.cursor++;continue}break}for(x.cursor=t;;)for(n=x.cursor;;){if(i=x.cursor,x.in_grouping(L,97,249)){if(x.bra=x.cursor,o=x.cursor,e("u","U",i))break;if(x.cursor=o,e("i","I",i))break}if(x.cursor=i,x.cursor>=x.limit)return void(x.cursor=n);x.cursor++}}function o(e){if(x.cursor=e,!x.in_grouping(L,97,249))return!1;for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function t(){if(x.in_grouping(L,97,249)){var e=x.cursor;if(x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return o(e);x.cursor++}return!0}return o(e)}return!1}function s(){var e,r=x.cursor;if(!t()){if(x.cursor=r,!x.out_grouping(L,97,249))return;if(e=x.cursor,x.out_grouping(L,97,249)){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return x.cursor=e,void(x.in_grouping(L,97,249)&&x.cursor=x.limit)return;x.cursor++}k=x.cursor}function a(){for(;!x.in_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}for(;!x.out_grouping(L,97,249);){if(x.cursor>=x.limit)return!1;x.cursor++}return!0}function u(){var e=x.cursor;k=x.limit,p=k,g=k,s(),x.cursor=e,a()&&(p=x.cursor,a()&&(g=x.cursor))}function c(){for(var e;;){if(x.bra=x.cursor,!(e=x.find_among(q,3)))break;switch(x.ket=x.cursor,e){case 1:x.slice_from("i");break;case 2:x.slice_from("u");break;case 3:if(x.cursor>=x.limit)return;x.cursor++}}}function w(){return k<=x.cursor}function l(){return p<=x.cursor}function m(){return g<=x.cursor}function f(){var e;if(x.ket=x.cursor,x.find_among_b(C,37)&&(x.bra=x.cursor,(e=x.find_among_b(z,5))&&w()))switch(e){case 1:x.slice_del();break;case 2:x.slice_from("e")}}function v(){var e;if(x.ket=x.cursor,!(e=x.find_among_b(S,51)))return!1;switch(x.bra=x.cursor,e){case 1:if(!m())return!1;x.slice_del();break;case 2:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del());break;case 3:if(!m())return!1;x.slice_from("log");break;case 4:if(!m())return!1;x.slice_from("u");break;case 5:if(!m())return!1;x.slice_from("ente");break;case 6:if(!w())return!1;x.slice_del();break;case 7:if(!l())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(P,4),e&&(x.bra=x.cursor,m()&&(x.slice_del(),1==e&&(x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&x.slice_del()))));break;case 8:if(!m())return!1;x.slice_del(),x.ket=x.cursor,e=x.find_among_b(F,3),e&&(x.bra=x.cursor,1==e&&m()&&x.slice_del());break;case 9:if(!m())return!1;x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"at")&&(x.bra=x.cursor,m()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(2,"ic")&&(x.bra=x.cursor,m()&&x.slice_del())))}return!0}function b(){var e,r;x.cursor>=k&&(r=x.limit_backward,x.limit_backward=k,x.ket=x.cursor,e=x.find_among_b(W,87),e&&(x.bra=x.cursor,1==e&&x.slice_del()),x.limit_backward=r)}function d(){var e=x.limit-x.cursor;if(x.ket=x.cursor,x.in_grouping_b(y,97,242)&&(x.bra=x.cursor,w()&&(x.slice_del(),x.ket=x.cursor,x.eq_s_b(1,"i")&&(x.bra=x.cursor,w()))))return void x.slice_del();x.cursor=x.limit-e}function _(){d(),x.ket=x.cursor,x.eq_s_b(1,"h")&&(x.bra=x.cursor,x.in_grouping_b(U,99,103)&&w()&&x.slice_del())}var g,p,k,h=[new r("",-1,7),new r("qu",0,6),new r("á",0,1),new r("é",0,2),new r("í",0,3),new r("ó",0,4),new r("ú",0,5)],q=[new r("",-1,3),new r("I",0,1),new r("U",0,2)],C=[new r("la",-1,-1),new r("cela",0,-1),new r("gliela",0,-1),new r("mela",0,-1),new r("tela",0,-1),new r("vela",0,-1),new r("le",-1,-1),new r("cele",6,-1),new r("gliele",6,-1),new r("mele",6,-1),new r("tele",6,-1),new r("vele",6,-1),new r("ne",-1,-1),new r("cene",12,-1),new r("gliene",12,-1),new r("mene",12,-1),new r("sene",12,-1),new r("tene",12,-1),new r("vene",12,-1),new r("ci",-1,-1),new r("li",-1,-1),new r("celi",20,-1),new r("glieli",20,-1),new r("meli",20,-1),new r("teli",20,-1),new r("veli",20,-1),new r("gli",20,-1),new r("mi",-1,-1),new r("si",-1,-1),new r("ti",-1,-1),new r("vi",-1,-1),new r("lo",-1,-1),new r("celo",31,-1),new r("glielo",31,-1),new r("melo",31,-1),new r("telo",31,-1),new r("velo",31,-1)],z=[new r("ando",-1,1),new r("endo",-1,1),new r("ar",-1,2),new r("er",-1,2),new r("ir",-1,2)],P=[new r("ic",-1,-1),new r("abil",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],F=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],S=[new r("ica",-1,1),new r("logia",-1,3),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,9),new r("anza",-1,1),new r("enza",-1,5),new r("ice",-1,1),new r("atrice",7,1),new r("iche",-1,1),new r("logie",-1,3),new r("abile",-1,1),new r("ibile",-1,1),new r("usione",-1,4),new r("azione",-1,2),new r("uzione",-1,4),new r("atore",-1,2),new r("ose",-1,1),new r("ante",-1,1),new r("mente",-1,1),new r("amente",19,7),new r("iste",-1,1),new r("ive",-1,9),new r("anze",-1,1),new r("enze",-1,5),new r("ici",-1,1),new r("atrici",25,1),new r("ichi",-1,1),new r("abili",-1,1),new r("ibili",-1,1),new r("ismi",-1,1),new r("usioni",-1,4),new r("azioni",-1,2),new r("uzioni",-1,4),new r("atori",-1,2),new r("osi",-1,1),new r("anti",-1,1),new r("amenti",-1,6),new r("imenti",-1,6),new r("isti",-1,1),new r("ivi",-1,9),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,6),new r("imento",-1,6),new r("ivo",-1,9),new r("ità",-1,8),new r("istà",-1,1),new r("istè",-1,1),new r("istì",-1,1)],W=[new r("isca",-1,1),new r("enda",-1,1),new r("ata",-1,1),new r("ita",-1,1),new r("uta",-1,1),new r("ava",-1,1),new r("eva",-1,1),new r("iva",-1,1),new r("erebbe",-1,1),new r("irebbe",-1,1),new r("isce",-1,1),new r("ende",-1,1),new r("are",-1,1),new r("ere",-1,1),new r("ire",-1,1),new r("asse",-1,1),new r("ate",-1,1),new r("avate",16,1),new r("evate",16,1),new r("ivate",16,1),new r("ete",-1,1),new r("erete",20,1),new r("irete",20,1),new r("ite",-1,1),new r("ereste",-1,1),new r("ireste",-1,1),new r("ute",-1,1),new r("erai",-1,1),new r("irai",-1,1),new r("isci",-1,1),new r("endi",-1,1),new r("erei",-1,1),new r("irei",-1,1),new r("assi",-1,1),new r("ati",-1,1),new r("iti",-1,1),new r("eresti",-1,1),new r("iresti",-1,1),new r("uti",-1,1),new r("avi",-1,1),new r("evi",-1,1),new r("ivi",-1,1),new r("isco",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("Yamo",-1,1),new r("iamo",-1,1),new r("avamo",-1,1),new r("evamo",-1,1),new r("ivamo",-1,1),new r("eremo",-1,1),new r("iremo",-1,1),new r("assimo",-1,1),new r("ammo",-1,1),new r("emmo",-1,1),new r("eremmo",54,1),new r("iremmo",54,1),new r("immo",-1,1),new r("ano",-1,1),new r("iscano",58,1),new r("avano",58,1),new r("evano",58,1),new r("ivano",58,1),new r("eranno",-1,1),new r("iranno",-1,1),new r("ono",-1,1),new r("iscono",65,1),new r("arono",65,1),new r("erono",65,1),new r("irono",65,1),new r("erebbero",-1,1),new r("irebbero",-1,1),new r("assero",-1,1),new r("essero",-1,1),new r("issero",-1,1),new r("ato",-1,1),new r("ito",-1,1),new r("uto",-1,1),new r("avo",-1,1),new r("evo",-1,1),new r("ivo",-1,1),new r("ar",-1,1),new r("ir",-1,1),new r("erà",-1,1),new r("irà",-1,1),new r("erò",-1,1),new r("irò",-1,1)],L=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],y=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],U=[17],x=new n;this.setCurrent=function(e){x.setCurrent(e)},this.getCurrent=function(){return x.getCurrent()},this.stem=function(){var e=x.cursor;return i(),x.cursor=e,u(),x.limit_backward=e,x.cursor=x.limit,f(),x.cursor=x.limit,v()||(x.cursor=x.limit,b()),x.cursor=x.limit,_(),x.cursor=x.limit_backward,c(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ja.min.js b/assets/javascripts/lunr/min/lunr.ja.min.js new file mode 100644 index 000000000..5f254ebe9 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ja.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n=C.limit)break;C.cursor++;continue}break}for(C.cursor=o,C.bra=o,C.eq_s(1,"y")?(C.ket=C.cursor,C.slice_from("Y")):C.cursor=o;;)if(e=C.cursor,C.in_grouping(q,97,232)){if(i=C.cursor,C.bra=i,C.eq_s(1,"i"))C.ket=C.cursor,C.in_grouping(q,97,232)&&(C.slice_from("I"),C.cursor=e);else if(C.cursor=i,C.eq_s(1,"y"))C.ket=C.cursor,C.slice_from("Y"),C.cursor=e;else if(n(e))break}else if(n(e))break}function n(r){return C.cursor=r,r>=C.limit||(C.cursor++,!1)}function o(){_=C.limit,d=_,t()||(_=C.cursor,_<3&&(_=3),t()||(d=C.cursor))}function t(){for(;!C.in_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}for(;!C.out_grouping(q,97,232);){if(C.cursor>=C.limit)return!0;C.cursor++}return!1}function s(){for(var r;;)if(C.bra=C.cursor,r=C.find_among(p,3))switch(C.ket=C.cursor,r){case 1:C.slice_from("y");break;case 2:C.slice_from("i");break;case 3:if(C.cursor>=C.limit)return;C.cursor++}}function u(){return _<=C.cursor}function c(){return d<=C.cursor}function a(){var r=C.limit-C.cursor;C.find_among_b(g,3)&&(C.cursor=C.limit-r,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del()))}function l(){var r;w=!1,C.ket=C.cursor,C.eq_s_b(1,"e")&&(C.bra=C.cursor,u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.slice_del(),w=!0,a())))}function m(){var r;u()&&(r=C.limit-C.cursor,C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-r,C.eq_s_b(3,"gem")||(C.cursor=C.limit-r,C.slice_del(),a())))}function f(){var r,e,i,n,o,t,s=C.limit-C.cursor;if(C.ket=C.cursor,r=C.find_among_b(h,5))switch(C.bra=C.cursor,r){case 1:u()&&C.slice_from("heid");break;case 2:m();break;case 3:u()&&C.out_grouping_b(j,97,232)&&C.slice_del()}if(C.cursor=C.limit-s,l(),C.cursor=C.limit-s,C.ket=C.cursor,C.eq_s_b(4,"heid")&&(C.bra=C.cursor,c()&&(e=C.limit-C.cursor,C.eq_s_b(1,"c")||(C.cursor=C.limit-e,C.slice_del(),C.ket=C.cursor,C.eq_s_b(2,"en")&&(C.bra=C.cursor,m())))),C.cursor=C.limit-s,C.ket=C.cursor,r=C.find_among_b(k,6))switch(C.bra=C.cursor,r){case 1:if(c()){if(C.slice_del(),i=C.limit-C.cursor,C.ket=C.cursor,C.eq_s_b(2,"ig")&&(C.bra=C.cursor,c()&&(n=C.limit-C.cursor,!C.eq_s_b(1,"e")))){C.cursor=C.limit-n,C.slice_del();break}C.cursor=C.limit-i,a()}break;case 2:c()&&(o=C.limit-C.cursor,C.eq_s_b(1,"e")||(C.cursor=C.limit-o,C.slice_del()));break;case 3:c()&&(C.slice_del(),l());break;case 4:c()&&C.slice_del();break;case 5:c()&&w&&C.slice_del()}C.cursor=C.limit-s,C.out_grouping_b(z,73,232)&&(t=C.limit-C.cursor,C.find_among_b(v,4)&&C.out_grouping_b(q,97,232)&&(C.cursor=C.limit-t,C.ket=C.cursor,C.cursor>C.limit_backward&&(C.cursor--,C.bra=C.cursor,C.slice_del())))}var d,_,w,b=[new e("",-1,6),new e("á",0,1),new e("ä",0,1),new e("é",0,2),new e("ë",0,2),new e("í",0,3),new e("ï",0,3),new e("ó",0,4),new e("ö",0,4),new e("ú",0,5),new e("ü",0,5)],p=[new e("",-1,3),new e("I",0,2),new e("Y",0,1)],g=[new e("dd",-1,-1),new e("kk",-1,-1),new e("tt",-1,-1)],h=[new e("ene",-1,2),new e("se",-1,3),new e("en",-1,2),new e("heden",2,1),new e("s",-1,3)],k=[new e("end",-1,1),new e("ig",-1,2),new e("ing",-1,1),new e("lijk",-1,3),new e("baar",-1,4),new e("bar",-1,5)],v=[new e("aa",-1,-1),new e("ee",-1,-1),new e("oo",-1,-1),new e("uu",-1,-1)],q=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],z=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],j=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],C=new i;this.setCurrent=function(r){C.setCurrent(r)},this.getCurrent=function(){return C.getCurrent()},this.stem=function(){var e=C.cursor;return r(),C.cursor=e,o(),C.limit_backward=e,C.cursor=C.limit,f(),C.cursor=C.limit_backward,s(),!0}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.no.min.js b/assets/javascripts/lunr/min/lunr.no.min.js new file mode 100644 index 000000000..92bc7e4e8 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.no.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Norwegian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.pt.min.js b/assets/javascripts/lunr/min/lunr.pt.min.js new file mode 100644 index 000000000..6c16996d6 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.pt.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Portuguese` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=function(){var r=e.stemmerSupport.Among,s=e.stemmerSupport.SnowballProgram,n=new function(){function e(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(k,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("a~");continue;case 2:z.slice_from("o~");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function n(){if(z.out_grouping(y,97,250)){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!0;z.cursor++}return!1}return!0}function i(){if(z.in_grouping(y,97,250))for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return g=z.cursor,!0}function o(){var e,r,s=z.cursor;if(z.in_grouping(y,97,250))if(e=z.cursor,n()){if(z.cursor=e,i())return}else g=z.cursor;if(z.cursor=s,z.out_grouping(y,97,250)){if(r=z.cursor,n()){if(z.cursor=r,!z.in_grouping(y,97,250)||z.cursor>=z.limit)return;z.cursor++}g=z.cursor}}function t(){for(;!z.in_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}for(;!z.out_grouping(y,97,250);){if(z.cursor>=z.limit)return!1;z.cursor++}return!0}function a(){var e=z.cursor;g=z.limit,b=g,h=g,o(),z.cursor=e,t()&&(b=z.cursor,t()&&(h=z.cursor))}function u(){for(var e;;){if(z.bra=z.cursor,e=z.find_among(q,3))switch(z.ket=z.cursor,e){case 1:z.slice_from("ã");continue;case 2:z.slice_from("õ");continue;case 3:if(z.cursor>=z.limit)break;z.cursor++;continue}break}}function w(){return g<=z.cursor}function m(){return b<=z.cursor}function c(){return h<=z.cursor}function l(){var e;if(z.ket=z.cursor,!(e=z.find_among_b(F,45)))return!1;switch(z.bra=z.cursor,e){case 1:if(!c())return!1;z.slice_del();break;case 2:if(!c())return!1;z.slice_from("log");break;case 3:if(!c())return!1;z.slice_from("u");break;case 4:if(!c())return!1;z.slice_from("ente");break;case 5:if(!m())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(j,4),e&&(z.bra=z.cursor,c()&&(z.slice_del(),1==e&&(z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del()))));break;case 6:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(C,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 7:if(!c())return!1;z.slice_del(),z.ket=z.cursor,e=z.find_among_b(P,3),e&&(z.bra=z.cursor,1==e&&c()&&z.slice_del());break;case 8:if(!c())return!1;z.slice_del(),z.ket=z.cursor,z.eq_s_b(2,"at")&&(z.bra=z.cursor,c()&&z.slice_del());break;case 9:if(!w()||!z.eq_s_b(1,"e"))return!1;z.slice_from("ir")}return!0}function f(){var e,r;if(z.cursor>=g){if(r=z.limit_backward,z.limit_backward=g,z.ket=z.cursor,e=z.find_among_b(S,120))return z.bra=z.cursor,1==e&&z.slice_del(),z.limit_backward=r,!0;z.limit_backward=r}return!1}function d(){var e;z.ket=z.cursor,(e=z.find_among_b(W,7))&&(z.bra=z.cursor,1==e&&w()&&z.slice_del())}function v(e,r){if(z.eq_s_b(1,e)){z.bra=z.cursor;var s=z.limit-z.cursor;if(z.eq_s_b(1,r))return z.cursor=z.limit-s,w()&&z.slice_del(),!1}return!0}function p(){var e;if(z.ket=z.cursor,e=z.find_among_b(L,4))switch(z.bra=z.cursor,e){case 1:w()&&(z.slice_del(),z.ket=z.cursor,z.limit-z.cursor,v("u","g")&&v("i","c"));break;case 2:z.slice_from("c")}}function _(){if(!l()&&(z.cursor=z.limit,!f()))return z.cursor=z.limit,void d();z.cursor=z.limit,z.ket=z.cursor,z.eq_s_b(1,"i")&&(z.bra=z.cursor,z.eq_s_b(1,"c")&&(z.cursor=z.limit,w()&&z.slice_del()))}var h,b,g,k=[new r("",-1,3),new r("ã",0,1),new r("õ",0,2)],q=[new r("",-1,3),new r("a~",0,1),new r("o~",0,2)],j=[new r("ic",-1,-1),new r("ad",-1,-1),new r("os",-1,-1),new r("iv",-1,1)],C=[new r("ante",-1,1),new r("avel",-1,1),new r("ível",-1,1)],P=[new r("ic",-1,1),new r("abil",-1,1),new r("iv",-1,1)],F=[new r("ica",-1,1),new r("ância",-1,1),new r("ência",-1,4),new r("ira",-1,9),new r("adora",-1,1),new r("osa",-1,1),new r("ista",-1,1),new r("iva",-1,8),new r("eza",-1,1),new r("logía",-1,2),new r("idade",-1,7),new r("ante",-1,1),new r("mente",-1,6),new r("amente",12,5),new r("ável",-1,1),new r("ível",-1,1),new r("ución",-1,3),new r("ico",-1,1),new r("ismo",-1,1),new r("oso",-1,1),new r("amento",-1,1),new r("imento",-1,1),new r("ivo",-1,8),new r("aça~o",-1,1),new r("ador",-1,1),new r("icas",-1,1),new r("ências",-1,4),new r("iras",-1,9),new r("adoras",-1,1),new r("osas",-1,1),new r("istas",-1,1),new r("ivas",-1,8),new r("ezas",-1,1),new r("logías",-1,2),new r("idades",-1,7),new r("uciones",-1,3),new r("adores",-1,1),new r("antes",-1,1),new r("aço~es",-1,1),new r("icos",-1,1),new r("ismos",-1,1),new r("osos",-1,1),new r("amentos",-1,1),new r("imentos",-1,1),new r("ivos",-1,8)],S=[new r("ada",-1,1),new r("ida",-1,1),new r("ia",-1,1),new r("aria",2,1),new r("eria",2,1),new r("iria",2,1),new r("ara",-1,1),new r("era",-1,1),new r("ira",-1,1),new r("ava",-1,1),new r("asse",-1,1),new r("esse",-1,1),new r("isse",-1,1),new r("aste",-1,1),new r("este",-1,1),new r("iste",-1,1),new r("ei",-1,1),new r("arei",16,1),new r("erei",16,1),new r("irei",16,1),new r("am",-1,1),new r("iam",20,1),new r("ariam",21,1),new r("eriam",21,1),new r("iriam",21,1),new r("aram",20,1),new r("eram",20,1),new r("iram",20,1),new r("avam",20,1),new r("em",-1,1),new r("arem",29,1),new r("erem",29,1),new r("irem",29,1),new r("assem",29,1),new r("essem",29,1),new r("issem",29,1),new r("ado",-1,1),new r("ido",-1,1),new r("ando",-1,1),new r("endo",-1,1),new r("indo",-1,1),new r("ara~o",-1,1),new r("era~o",-1,1),new r("ira~o",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("ir",-1,1),new r("as",-1,1),new r("adas",47,1),new r("idas",47,1),new r("ias",47,1),new r("arias",50,1),new r("erias",50,1),new r("irias",50,1),new r("aras",47,1),new r("eras",47,1),new r("iras",47,1),new r("avas",47,1),new r("es",-1,1),new r("ardes",58,1),new r("erdes",58,1),new r("irdes",58,1),new r("ares",58,1),new r("eres",58,1),new r("ires",58,1),new r("asses",58,1),new r("esses",58,1),new r("isses",58,1),new r("astes",58,1),new r("estes",58,1),new r("istes",58,1),new r("is",-1,1),new r("ais",71,1),new r("eis",71,1),new r("areis",73,1),new r("ereis",73,1),new r("ireis",73,1),new r("áreis",73,1),new r("éreis",73,1),new r("íreis",73,1),new r("ásseis",73,1),new r("ésseis",73,1),new r("ísseis",73,1),new r("áveis",73,1),new r("íeis",73,1),new r("aríeis",84,1),new r("eríeis",84,1),new r("iríeis",84,1),new r("ados",-1,1),new r("idos",-1,1),new r("amos",-1,1),new r("áramos",90,1),new r("éramos",90,1),new r("íramos",90,1),new r("ávamos",90,1),new r("íamos",90,1),new r("aríamos",95,1),new r("eríamos",95,1),new r("iríamos",95,1),new r("emos",-1,1),new r("aremos",99,1),new r("eremos",99,1),new r("iremos",99,1),new r("ássemos",99,1),new r("êssemos",99,1),new r("íssemos",99,1),new r("imos",-1,1),new r("armos",-1,1),new r("ermos",-1,1),new r("irmos",-1,1),new r("ámos",-1,1),new r("arás",-1,1),new r("erás",-1,1),new r("irás",-1,1),new r("eu",-1,1),new r("iu",-1,1),new r("ou",-1,1),new r("ará",-1,1),new r("erá",-1,1),new r("irá",-1,1)],W=[new r("a",-1,1),new r("i",-1,1),new r("o",-1,1),new r("os",-1,1),new r("á",-1,1),new r("í",-1,1),new r("ó",-1,1)],L=[new r("e",-1,1),new r("ç",-1,2),new r("é",-1,1),new r("ê",-1,1)],y=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],z=new s;this.setCurrent=function(e){z.setCurrent(e)},this.getCurrent=function(){return z.getCurrent()},this.stem=function(){var r=z.cursor;return e(),z.cursor=r,a(),z.limit_backward=r,z.cursor=z.limit,_(),z.cursor=z.limit,p(),z.cursor=z.limit_backward,u(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ro.min.js b/assets/javascripts/lunr/min/lunr.ro.min.js new file mode 100644 index 000000000..727714018 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ro.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Romanian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=function(){var i=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,n=new function(){function e(e,i){L.eq_s(1,e)&&(L.ket=L.cursor,L.in_grouping(W,97,259)&&L.slice_from(i))}function n(){for(var i,r;;){if(i=L.cursor,L.in_grouping(W,97,259)&&(r=L.cursor,L.bra=r,e("u","U"),L.cursor=r,e("i","I")),L.cursor=i,L.cursor>=L.limit)break;L.cursor++}}function t(){if(L.out_grouping(W,97,259)){for(;!L.in_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}return!0}function a(){if(L.in_grouping(W,97,259))for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!0;L.cursor++}return!1}function o(){var e,i,r=L.cursor;if(L.in_grouping(W,97,259)){if(e=L.cursor,!t())return void(h=L.cursor);if(L.cursor=e,!a())return void(h=L.cursor)}L.cursor=r,L.out_grouping(W,97,259)&&(i=L.cursor,t()&&(L.cursor=i,L.in_grouping(W,97,259)&&L.cursor=L.limit)return!1;L.cursor++}for(;!L.out_grouping(W,97,259);){if(L.cursor>=L.limit)return!1;L.cursor++}return!0}function c(){var e=L.cursor;h=L.limit,k=h,g=h,o(),L.cursor=e,u()&&(k=L.cursor,u()&&(g=L.cursor))}function s(){for(var e;;){if(L.bra=L.cursor,e=L.find_among(z,3))switch(L.ket=L.cursor,e){case 1:L.slice_from("i");continue;case 2:L.slice_from("u");continue;case 3:if(L.cursor>=L.limit)break;L.cursor++;continue}break}}function w(){return h<=L.cursor}function m(){return k<=L.cursor}function l(){return g<=L.cursor}function f(){var e,i;if(L.ket=L.cursor,(e=L.find_among_b(C,16))&&(L.bra=L.cursor,m()))switch(e){case 1:L.slice_del();break;case 2:L.slice_from("a");break;case 3:L.slice_from("e");break;case 4:L.slice_from("i");break;case 5:i=L.limit-L.cursor,L.eq_s_b(2,"ab")||(L.cursor=L.limit-i,L.slice_from("i"));break;case 6:L.slice_from("at");break;case 7:L.slice_from("aţi")}}function p(){var e,i=L.limit-L.cursor;if(L.ket=L.cursor,(e=L.find_among_b(P,46))&&(L.bra=L.cursor,m())){switch(e){case 1:L.slice_from("abil");break;case 2:L.slice_from("ibil");break;case 3:L.slice_from("iv");break;case 4:L.slice_from("ic");break;case 5:L.slice_from("at");break;case 6:L.slice_from("it")}return _=!0,L.cursor=L.limit-i,!0}return!1}function d(){var e,i;for(_=!1;;)if(i=L.limit-L.cursor,!p()){L.cursor=L.limit-i;break}if(L.ket=L.cursor,(e=L.find_among_b(F,62))&&(L.bra=L.cursor,l())){switch(e){case 1:L.slice_del();break;case 2:L.eq_s_b(1,"ţ")&&(L.bra=L.cursor,L.slice_from("t"));break;case 3:L.slice_from("ist")}_=!0}}function b(){var e,i,r;if(L.cursor>=h){if(i=L.limit_backward,L.limit_backward=h,L.ket=L.cursor,e=L.find_among_b(q,94))switch(L.bra=L.cursor,e){case 1:if(r=L.limit-L.cursor,!L.out_grouping_b(W,97,259)&&(L.cursor=L.limit-r,!L.eq_s_b(1,"u")))break;case 2:L.slice_del()}L.limit_backward=i}}function v(){var e;L.ket=L.cursor,(e=L.find_among_b(S,5))&&(L.bra=L.cursor,w()&&1==e&&L.slice_del())}var _,g,k,h,z=[new i("",-1,3),new i("I",0,1),new i("U",0,2)],C=[new i("ea",-1,3),new i("aţia",-1,7),new i("aua",-1,2),new i("iua",-1,4),new i("aţie",-1,7),new i("ele",-1,3),new i("ile",-1,5),new i("iile",6,4),new i("iei",-1,4),new i("atei",-1,6),new i("ii",-1,4),new i("ului",-1,1),new i("ul",-1,1),new i("elor",-1,3),new i("ilor",-1,4),new i("iilor",14,4)],P=[new i("icala",-1,4),new i("iciva",-1,4),new i("ativa",-1,5),new i("itiva",-1,6),new i("icale",-1,4),new i("aţiune",-1,5),new i("iţiune",-1,6),new i("atoare",-1,5),new i("itoare",-1,6),new i("ătoare",-1,5),new i("icitate",-1,4),new i("abilitate",-1,1),new i("ibilitate",-1,2),new i("ivitate",-1,3),new i("icive",-1,4),new i("ative",-1,5),new i("itive",-1,6),new i("icali",-1,4),new i("atori",-1,5),new i("icatori",18,4),new i("itori",-1,6),new i("ători",-1,5),new i("icitati",-1,4),new i("abilitati",-1,1),new i("ivitati",-1,3),new i("icivi",-1,4),new i("ativi",-1,5),new i("itivi",-1,6),new i("icităi",-1,4),new i("abilităi",-1,1),new i("ivităi",-1,3),new i("icităţi",-1,4),new i("abilităţi",-1,1),new i("ivităţi",-1,3),new i("ical",-1,4),new i("ator",-1,5),new i("icator",35,4),new i("itor",-1,6),new i("ător",-1,5),new i("iciv",-1,4),new i("ativ",-1,5),new i("itiv",-1,6),new i("icală",-1,4),new i("icivă",-1,4),new i("ativă",-1,5),new i("itivă",-1,6)],F=[new i("ica",-1,1),new i("abila",-1,1),new i("ibila",-1,1),new i("oasa",-1,1),new i("ata",-1,1),new i("ita",-1,1),new i("anta",-1,1),new i("ista",-1,3),new i("uta",-1,1),new i("iva",-1,1),new i("ic",-1,1),new i("ice",-1,1),new i("abile",-1,1),new i("ibile",-1,1),new i("isme",-1,3),new i("iune",-1,2),new i("oase",-1,1),new i("ate",-1,1),new i("itate",17,1),new i("ite",-1,1),new i("ante",-1,1),new i("iste",-1,3),new i("ute",-1,1),new i("ive",-1,1),new i("ici",-1,1),new i("abili",-1,1),new i("ibili",-1,1),new i("iuni",-1,2),new i("atori",-1,1),new i("osi",-1,1),new i("ati",-1,1),new i("itati",30,1),new i("iti",-1,1),new i("anti",-1,1),new i("isti",-1,3),new i("uti",-1,1),new i("işti",-1,3),new i("ivi",-1,1),new i("ităi",-1,1),new i("oşi",-1,1),new i("ităţi",-1,1),new i("abil",-1,1),new i("ibil",-1,1),new i("ism",-1,3),new i("ator",-1,1),new i("os",-1,1),new i("at",-1,1),new i("it",-1,1),new i("ant",-1,1),new i("ist",-1,3),new i("ut",-1,1),new i("iv",-1,1),new i("ică",-1,1),new i("abilă",-1,1),new i("ibilă",-1,1),new i("oasă",-1,1),new i("ată",-1,1),new i("ită",-1,1),new i("antă",-1,1),new i("istă",-1,3),new i("ută",-1,1),new i("ivă",-1,1)],q=[new i("ea",-1,1),new i("ia",-1,1),new i("esc",-1,1),new i("ăsc",-1,1),new i("ind",-1,1),new i("ând",-1,1),new i("are",-1,1),new i("ere",-1,1),new i("ire",-1,1),new i("âre",-1,1),new i("se",-1,2),new i("ase",10,1),new i("sese",10,2),new i("ise",10,1),new i("use",10,1),new i("âse",10,1),new i("eşte",-1,1),new i("ăşte",-1,1),new i("eze",-1,1),new i("ai",-1,1),new i("eai",19,1),new i("iai",19,1),new i("sei",-1,2),new i("eşti",-1,1),new i("ăşti",-1,1),new i("ui",-1,1),new i("ezi",-1,1),new i("âi",-1,1),new i("aşi",-1,1),new i("seşi",-1,2),new i("aseşi",29,1),new i("seseşi",29,2),new i("iseşi",29,1),new i("useşi",29,1),new i("âseşi",29,1),new i("işi",-1,1),new i("uşi",-1,1),new i("âşi",-1,1),new i("aţi",-1,2),new i("eaţi",38,1),new i("iaţi",38,1),new i("eţi",-1,2),new i("iţi",-1,2),new i("âţi",-1,2),new i("arăţi",-1,1),new i("serăţi",-1,2),new i("aserăţi",45,1),new i("seserăţi",45,2),new i("iserăţi",45,1),new i("userăţi",45,1),new i("âserăţi",45,1),new i("irăţi",-1,1),new i("urăţi",-1,1),new i("ârăţi",-1,1),new i("am",-1,1),new i("eam",54,1),new i("iam",54,1),new i("em",-1,2),new i("asem",57,1),new i("sesem",57,2),new i("isem",57,1),new i("usem",57,1),new i("âsem",57,1),new i("im",-1,2),new i("âm",-1,2),new i("ăm",-1,2),new i("arăm",65,1),new i("serăm",65,2),new i("aserăm",67,1),new i("seserăm",67,2),new i("iserăm",67,1),new i("userăm",67,1),new i("âserăm",67,1),new i("irăm",65,1),new i("urăm",65,1),new i("ârăm",65,1),new i("au",-1,1),new i("eau",76,1),new i("iau",76,1),new i("indu",-1,1),new i("ându",-1,1),new i("ez",-1,1),new i("ească",-1,1),new i("ară",-1,1),new i("seră",-1,2),new i("aseră",84,1),new i("seseră",84,2),new i("iseră",84,1),new i("useră",84,1),new i("âseră",84,1),new i("iră",-1,1),new i("ură",-1,1),new i("âră",-1,1),new i("ează",-1,1)],S=[new i("a",-1,1),new i("e",-1,1),new i("ie",1,1),new i("i",-1,1),new i("ă",-1,1)],W=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],L=new r;this.setCurrent=function(e){L.setCurrent(e)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){var e=L.cursor;return n(),L.cursor=e,c(),L.limit_backward=e,L.cursor=L.limit,f(),L.cursor=L.limit,d(),L.cursor=L.limit,_||(L.cursor=L.limit,b(),L.cursor=L.limit),v(),L.cursor=L.limit_backward,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ru.min.js b/assets/javascripts/lunr/min/lunr.ru.min.js new file mode 100644 index 000000000..186cc485c --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ru.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Russian` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=function(){var n=e.stemmerSupport.Among,r=e.stemmerSupport.SnowballProgram,t=new function(){function e(){for(;!W.in_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function t(){for(;!W.out_grouping(S,1072,1103);){if(W.cursor>=W.limit)return!1;W.cursor++}return!0}function w(){b=W.limit,_=b,e()&&(b=W.cursor,t()&&e()&&t()&&(_=W.cursor))}function i(){return _<=W.cursor}function u(e,n){var r,t;if(W.ket=W.cursor,r=W.find_among_b(e,n)){switch(W.bra=W.cursor,r){case 1:if(t=W.limit-W.cursor,!W.eq_s_b(1,"а")&&(W.cursor=W.limit-t,!W.eq_s_b(1,"я")))return!1;case 2:W.slice_del()}return!0}return!1}function o(){return u(h,9)}function s(e,n){var r;return W.ket=W.cursor,!!(r=W.find_among_b(e,n))&&(W.bra=W.cursor,1==r&&W.slice_del(),!0)}function c(){return s(g,26)}function m(){return!!c()&&(u(C,8),!0)}function f(){return s(k,2)}function l(){return u(P,46)}function a(){s(v,36)}function p(){var e;W.ket=W.cursor,(e=W.find_among_b(F,2))&&(W.bra=W.cursor,i()&&1==e&&W.slice_del())}function d(){var e;if(W.ket=W.cursor,e=W.find_among_b(q,4))switch(W.bra=W.cursor,e){case 1:if(W.slice_del(),W.ket=W.cursor,!W.eq_s_b(1,"н"))break;W.bra=W.cursor;case 2:if(!W.eq_s_b(1,"н"))break;case 3:W.slice_del()}}var _,b,h=[new n("в",-1,1),new n("ив",0,2),new n("ыв",0,2),new n("вши",-1,1),new n("ивши",3,2),new n("ывши",3,2),new n("вшись",-1,1),new n("ившись",6,2),new n("ывшись",6,2)],g=[new n("ее",-1,1),new n("ие",-1,1),new n("ое",-1,1),new n("ые",-1,1),new n("ими",-1,1),new n("ыми",-1,1),new n("ей",-1,1),new n("ий",-1,1),new n("ой",-1,1),new n("ый",-1,1),new n("ем",-1,1),new n("им",-1,1),new n("ом",-1,1),new n("ым",-1,1),new n("его",-1,1),new n("ого",-1,1),new n("ему",-1,1),new n("ому",-1,1),new n("их",-1,1),new n("ых",-1,1),new n("ею",-1,1),new n("ою",-1,1),new n("ую",-1,1),new n("юю",-1,1),new n("ая",-1,1),new n("яя",-1,1)],C=[new n("ем",-1,1),new n("нн",-1,1),new n("вш",-1,1),new n("ивш",2,2),new n("ывш",2,2),new n("щ",-1,1),new n("ющ",5,1),new n("ующ",6,2)],k=[new n("сь",-1,1),new n("ся",-1,1)],P=[new n("ла",-1,1),new n("ила",0,2),new n("ыла",0,2),new n("на",-1,1),new n("ена",3,2),new n("ете",-1,1),new n("ите",-1,2),new n("йте",-1,1),new n("ейте",7,2),new n("уйте",7,2),new n("ли",-1,1),new n("или",10,2),new n("ыли",10,2),new n("й",-1,1),new n("ей",13,2),new n("уй",13,2),new n("л",-1,1),new n("ил",16,2),new n("ыл",16,2),new n("ем",-1,1),new n("им",-1,2),new n("ым",-1,2),new n("н",-1,1),new n("ен",22,2),new n("ло",-1,1),new n("ило",24,2),new n("ыло",24,2),new n("но",-1,1),new n("ено",27,2),new n("нно",27,1),new n("ет",-1,1),new n("ует",30,2),new n("ит",-1,2),new n("ыт",-1,2),new n("ют",-1,1),new n("уют",34,2),new n("ят",-1,2),new n("ны",-1,1),new n("ены",37,2),new n("ть",-1,1),new n("ить",39,2),new n("ыть",39,2),new n("ешь",-1,1),new n("ишь",-1,2),new n("ю",-1,2),new n("ую",44,2)],v=[new n("а",-1,1),new n("ев",-1,1),new n("ов",-1,1),new n("е",-1,1),new n("ие",3,1),new n("ье",3,1),new n("и",-1,1),new n("еи",6,1),new n("ии",6,1),new n("ами",6,1),new n("ями",6,1),new n("иями",10,1),new n("й",-1,1),new n("ей",12,1),new n("ией",13,1),new n("ий",12,1),new n("ой",12,1),new n("ам",-1,1),new n("ем",-1,1),new n("ием",18,1),new n("ом",-1,1),new n("ям",-1,1),new n("иям",21,1),new n("о",-1,1),new n("у",-1,1),new n("ах",-1,1),new n("ях",-1,1),new n("иях",26,1),new n("ы",-1,1),new n("ь",-1,1),new n("ю",-1,1),new n("ию",30,1),new n("ью",30,1),new n("я",-1,1),new n("ия",33,1),new n("ья",33,1)],F=[new n("ост",-1,1),new n("ость",-1,1)],q=[new n("ейше",-1,1),new n("н",-1,2),new n("ейш",-1,1),new n("ь",-1,3)],S=[33,65,8,232],W=new r;this.setCurrent=function(e){W.setCurrent(e)},this.getCurrent=function(){return W.getCurrent()},this.stem=function(){return w(),W.cursor=W.limit,!(W.cursor=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.sv.min.js b/assets/javascripts/lunr/min/lunr.sv.min.js new file mode 100644 index 000000000..3e5eb6400 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.sv.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Swedish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.ta.min.js b/assets/javascripts/lunr/min/lunr.ta.min.js new file mode 100644 index 000000000..a644bed22 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.ta.min.js @@ -0,0 +1 @@ +!function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.th.min.js b/assets/javascripts/lunr/min/lunr.th.min.js new file mode 100644 index 000000000..dee3aac6e --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.th.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.tr.min.js b/assets/javascripts/lunr/min/lunr.tr.min.js new file mode 100644 index 000000000..563f6ec1f --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.tr.min.js @@ -0,0 +1,18 @@ +/*! + * Lunr languages, `Turkish` language + * https://github.com/MihaiValentin/lunr-languages + * + * Copyright 2014, Mihai Valentin + * http://www.mozilla.org/MPL/ + */ +/*! + * based on + * Snowball JavaScript Library v0.3 + * http://code.google.com/p/urim/ + * http://snowball.tartarus.org/ + * + * Copyright 2010, Oleg Mazko + * http://www.mozilla.org/MPL/ + */ + +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=function(){var i=r.stemmerSupport.Among,e=r.stemmerSupport.SnowballProgram,n=new function(){function r(r,i,e){for(;;){var n=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(r,i,e)){Dr.cursor=Dr.limit-n;break}if(Dr.cursor=Dr.limit-n,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function n(){var i,e;i=Dr.limit-Dr.cursor,r(Wr,97,305);for(var n=0;nDr.limit_backward&&(Dr.cursor--,e=Dr.limit-Dr.cursor,i()))?(Dr.cursor=Dr.limit-e,!0):(Dr.cursor=Dr.limit-n,r()?(Dr.cursor=Dr.limit-n,!1):(Dr.cursor=Dr.limit-n,!(Dr.cursor<=Dr.limit_backward)&&(Dr.cursor--,!!i()&&(Dr.cursor=Dr.limit-n,!0))))}function u(r){return t(r,function(){return Dr.in_grouping_b(Wr,97,305)})}function o(){return u(function(){return Dr.eq_s_b(1,"n")})}function s(){return u(function(){return Dr.eq_s_b(1,"s")})}function c(){return u(function(){return Dr.eq_s_b(1,"y")})}function l(){return t(function(){return Dr.in_grouping_b(Lr,105,305)},function(){return Dr.out_grouping_b(Wr,97,305)})}function a(){return Dr.find_among_b(ur,10)&&l()}function m(){return n()&&Dr.in_grouping_b(Lr,105,305)&&s()}function d(){return Dr.find_among_b(or,2)}function f(){return n()&&Dr.in_grouping_b(Lr,105,305)&&c()}function b(){return n()&&Dr.find_among_b(sr,4)}function w(){return n()&&Dr.find_among_b(cr,4)&&o()}function _(){return n()&&Dr.find_among_b(lr,2)&&c()}function k(){return n()&&Dr.find_among_b(ar,2)}function p(){return n()&&Dr.find_among_b(mr,4)}function g(){return n()&&Dr.find_among_b(dr,2)}function y(){return n()&&Dr.find_among_b(fr,4)}function z(){return n()&&Dr.find_among_b(br,2)}function v(){return n()&&Dr.find_among_b(wr,2)&&c()}function h(){return Dr.eq_s_b(2,"ki")}function q(){return n()&&Dr.find_among_b(_r,2)&&o()}function C(){return n()&&Dr.find_among_b(kr,4)&&c()}function P(){return n()&&Dr.find_among_b(pr,4)}function F(){return n()&&Dr.find_among_b(gr,4)&&c()}function S(){return Dr.find_among_b(yr,4)}function W(){return n()&&Dr.find_among_b(zr,2)}function L(){return n()&&Dr.find_among_b(vr,4)}function x(){return n()&&Dr.find_among_b(hr,8)}function A(){return Dr.find_among_b(qr,2)}function E(){return n()&&Dr.find_among_b(Cr,32)&&c()}function j(){return Dr.find_among_b(Pr,8)&&c()}function T(){return n()&&Dr.find_among_b(Fr,4)&&c()}function Z(){return Dr.eq_s_b(3,"ken")&&c()}function B(){var r=Dr.limit-Dr.cursor;return!(T()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,Z()))))}function D(){if(A()){var r=Dr.limit-Dr.cursor;if(S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T())return!1}return!0}function G(){if(W()){Dr.bra=Dr.cursor,Dr.slice_del();var r=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,x()||(Dr.cursor=Dr.limit-r,E()||(Dr.cursor=Dr.limit-r,j()||(Dr.cursor=Dr.limit-r,T()||(Dr.cursor=Dr.limit-r)))),nr=!1,!1}return!0}function H(){if(!L())return!0;var r=Dr.limit-Dr.cursor;return!E()&&(Dr.cursor=Dr.limit-r,!j())}function I(){var r,i=Dr.limit-Dr.cursor;return!(S()||(Dr.cursor=Dr.limit-i,F()||(Dr.cursor=Dr.limit-i,P()||(Dr.cursor=Dr.limit-i,C()))))||(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,T()||(Dr.cursor=Dr.limit-r),!1)}function J(){var r,i=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,nr=!0,B()&&(Dr.cursor=Dr.limit-i,D()&&(Dr.cursor=Dr.limit-i,G()&&(Dr.cursor=Dr.limit-i,H()&&(Dr.cursor=Dr.limit-i,I()))))){if(Dr.cursor=Dr.limit-i,!x())return;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,S()||(Dr.cursor=Dr.limit-r,W()||(Dr.cursor=Dr.limit-r,C()||(Dr.cursor=Dr.limit-r,P()||(Dr.cursor=Dr.limit-r,F()||(Dr.cursor=Dr.limit-r))))),T()||(Dr.cursor=Dr.limit-r)}Dr.bra=Dr.cursor,Dr.slice_del()}function K(){var r,i,e,n;if(Dr.ket=Dr.cursor,h()){if(r=Dr.limit-Dr.cursor,p())return Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,a()&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))),!0;if(Dr.cursor=Dr.limit-r,w()){if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,e=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-e,!m()&&(Dr.cursor=Dr.limit-e,!K())))return!0;Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}return!0}if(Dr.cursor=Dr.limit-r,g()){if(n=Dr.limit-Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-n,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-n,!K())return!1;return!0}}return!1}function M(r){if(Dr.ket=Dr.cursor,!g()&&(Dr.cursor=Dr.limit-r,!k()))return!1;var i=Dr.limit-Dr.cursor;if(d())Dr.bra=Dr.cursor,Dr.slice_del();else if(Dr.cursor=Dr.limit-i,m())Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K());else if(Dr.cursor=Dr.limit-i,!K())return!1;return!0}function N(r){if(Dr.ket=Dr.cursor,!z()&&(Dr.cursor=Dr.limit-r,!b()))return!1;var i=Dr.limit-Dr.cursor;return!(!m()&&(Dr.cursor=Dr.limit-i,!d()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)}function O(){var r,i=Dr.limit-Dr.cursor;return Dr.ket=Dr.cursor,!(!w()&&(Dr.cursor=Dr.limit-i,!v()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,!(!W()||(Dr.bra=Dr.cursor,Dr.slice_del(),!K()))||(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!(a()||(Dr.cursor=Dr.limit-r,m()||(Dr.cursor=Dr.limit-r,K())))||(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()),!0)))}function Q(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,!p()&&(Dr.cursor=Dr.limit-e,!f()&&(Dr.cursor=Dr.limit-e,!_())))return!1;if(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,r=Dr.limit-Dr.cursor,a())Dr.bra=Dr.cursor,Dr.slice_del(),i=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,W()||(Dr.cursor=Dr.limit-i);else if(Dr.cursor=Dr.limit-r,!W())return!0;return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,K(),!0}function R(){var r,i,e=Dr.limit-Dr.cursor;if(Dr.ket=Dr.cursor,W())return Dr.bra=Dr.cursor,Dr.slice_del(),void K();if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,q())if(Dr.bra=Dr.cursor,Dr.slice_del(),r=Dr.limit-Dr.cursor,Dr.ket=Dr.cursor,d())Dr.bra=Dr.cursor,Dr.slice_del();else{if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!a()&&(Dr.cursor=Dr.limit-r,!m())){if(Dr.cursor=Dr.limit-r,Dr.ket=Dr.cursor,!W())return;if(Dr.bra=Dr.cursor,Dr.slice_del(),!K())return}Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())}else if(Dr.cursor=Dr.limit-e,!M(e)&&(Dr.cursor=Dr.limit-e,!N(e))){if(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,y())return Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,i=Dr.limit-Dr.cursor,void(a()?(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K())):(Dr.cursor=Dr.limit-i,W()?(Dr.bra=Dr.cursor,Dr.slice_del(),K()):(Dr.cursor=Dr.limit-i,K())));if(Dr.cursor=Dr.limit-e,!O()){if(Dr.cursor=Dr.limit-e,d())return Dr.bra=Dr.cursor,void Dr.slice_del();Dr.cursor=Dr.limit-e,K()||(Dr.cursor=Dr.limit-e,Q()||(Dr.cursor=Dr.limit-e,Dr.ket=Dr.cursor,(a()||(Dr.cursor=Dr.limit-e,m()))&&(Dr.bra=Dr.cursor,Dr.slice_del(),Dr.ket=Dr.cursor,W()&&(Dr.bra=Dr.cursor,Dr.slice_del(),K()))))}}}function U(){var r;if(Dr.ket=Dr.cursor,r=Dr.find_among_b(Sr,4))switch(Dr.bra=Dr.cursor,r){case 1:Dr.slice_from("p");break;case 2:Dr.slice_from("ç");break;case 3:Dr.slice_from("t");break;case 4:Dr.slice_from("k")}}function V(){for(;;){var r=Dr.limit-Dr.cursor;if(Dr.in_grouping_b(Wr,97,305)){Dr.cursor=Dr.limit-r;break}if(Dr.cursor=Dr.limit-r,Dr.cursor<=Dr.limit_backward)return!1;Dr.cursor--}return!0}function X(r,i,e){if(Dr.cursor=Dr.limit-r,V()){var n=Dr.limit-Dr.cursor;if(!Dr.eq_s_b(1,i)&&(Dr.cursor=Dr.limit-n,!Dr.eq_s_b(1,e)))return!0;Dr.cursor=Dr.limit-r;var t=Dr.cursor;return Dr.insert(Dr.cursor,Dr.cursor,e),Dr.cursor=t,!1}return!0}function Y(){var r=Dr.limit-Dr.cursor;(Dr.eq_s_b(1,"d")||(Dr.cursor=Dr.limit-r,Dr.eq_s_b(1,"g")))&&X(r,"a","ı")&&X(r,"e","i")&&X(r,"o","u")&&X(r,"ö","ü")}function $(){for(var r,i=Dr.cursor,e=2;;){for(r=Dr.cursor;!Dr.in_grouping(Wr,97,305);){if(Dr.cursor>=Dr.limit)return Dr.cursor=r,!(e>0)&&(Dr.cursor=i,!0);Dr.cursor++}e--}}function rr(r,i,e){for(;!Dr.eq_s(i,e);){if(Dr.cursor>=Dr.limit)return!0;Dr.cursor++}return(tr=i)!=Dr.limit||(Dr.cursor=r,!1)}function ir(){var r=Dr.cursor;return!rr(r,2,"ad")||(Dr.cursor=r,!rr(r,5,"soyad"))}function er(){var r=Dr.cursor;return!ir()&&(Dr.limit_backward=r,Dr.cursor=Dr.limit,Y(),Dr.cursor=Dr.limit,U(),!0)}var nr,tr,ur=[new i("m",-1,-1),new i("n",-1,-1),new i("miz",-1,-1),new i("niz",-1,-1),new i("muz",-1,-1),new i("nuz",-1,-1),new i("müz",-1,-1),new i("nüz",-1,-1),new i("mız",-1,-1),new i("nız",-1,-1)],or=[new i("leri",-1,-1),new i("ları",-1,-1)],sr=[new i("ni",-1,-1),new i("nu",-1,-1),new i("nü",-1,-1),new i("nı",-1,-1)],cr=[new i("in",-1,-1),new i("un",-1,-1),new i("ün",-1,-1),new i("ın",-1,-1)],lr=[new i("a",-1,-1),new i("e",-1,-1)],ar=[new i("na",-1,-1),new i("ne",-1,-1)],mr=[new i("da",-1,-1),new i("ta",-1,-1),new i("de",-1,-1),new i("te",-1,-1)],dr=[new i("nda",-1,-1),new i("nde",-1,-1)],fr=[new i("dan",-1,-1),new i("tan",-1,-1),new i("den",-1,-1),new i("ten",-1,-1)],br=[new i("ndan",-1,-1),new i("nden",-1,-1)],wr=[new i("la",-1,-1),new i("le",-1,-1)],_r=[new i("ca",-1,-1),new i("ce",-1,-1)],kr=[new i("im",-1,-1),new i("um",-1,-1),new i("üm",-1,-1),new i("ım",-1,-1)],pr=[new i("sin",-1,-1),new i("sun",-1,-1),new i("sün",-1,-1),new i("sın",-1,-1)],gr=[new i("iz",-1,-1),new i("uz",-1,-1),new i("üz",-1,-1),new i("ız",-1,-1)],yr=[new i("siniz",-1,-1),new i("sunuz",-1,-1),new i("sünüz",-1,-1),new i("sınız",-1,-1)],zr=[new i("lar",-1,-1),new i("ler",-1,-1)],vr=[new i("niz",-1,-1),new i("nuz",-1,-1),new i("nüz",-1,-1),new i("nız",-1,-1)],hr=[new i("dir",-1,-1),new i("tir",-1,-1),new i("dur",-1,-1),new i("tur",-1,-1),new i("dür",-1,-1),new i("tür",-1,-1),new i("dır",-1,-1),new i("tır",-1,-1)],qr=[new i("casına",-1,-1),new i("cesine",-1,-1)],Cr=[new i("di",-1,-1),new i("ti",-1,-1),new i("dik",-1,-1),new i("tik",-1,-1),new i("duk",-1,-1),new i("tuk",-1,-1),new i("dük",-1,-1),new i("tük",-1,-1),new i("dık",-1,-1),new i("tık",-1,-1),new i("dim",-1,-1),new i("tim",-1,-1),new i("dum",-1,-1),new i("tum",-1,-1),new i("düm",-1,-1),new i("tüm",-1,-1),new i("dım",-1,-1),new i("tım",-1,-1),new i("din",-1,-1),new i("tin",-1,-1),new i("dun",-1,-1),new i("tun",-1,-1),new i("dün",-1,-1),new i("tün",-1,-1),new i("dın",-1,-1),new i("tın",-1,-1),new i("du",-1,-1),new i("tu",-1,-1),new i("dü",-1,-1),new i("tü",-1,-1),new i("dı",-1,-1),new i("tı",-1,-1)],Pr=[new i("sa",-1,-1),new i("se",-1,-1),new i("sak",-1,-1),new i("sek",-1,-1),new i("sam",-1,-1),new i("sem",-1,-1),new i("san",-1,-1),new i("sen",-1,-1)],Fr=[new i("miş",-1,-1),new i("muş",-1,-1),new i("müş",-1,-1),new i("mış",-1,-1)],Sr=[new i("b",-1,1),new i("c",-1,2),new i("d",-1,3),new i("ğ",-1,4)],Wr=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],Lr=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],xr=[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],Ar=[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],Er=[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],jr=[17],Tr=[65],Zr=[65],Br=[["a",xr,97,305],["e",Ar,101,252],["ı",Er,97,305],["i",jr,101,105],["o",Tr,111,117],["ö",Zr,246,252],["u",Tr,111,117]],Dr=new e;this.setCurrent=function(r){Dr.setCurrent(r)},this.getCurrent=function(){return Dr.getCurrent()},this.stem=function(){return!!($()&&(Dr.limit_backward=Dr.cursor,Dr.cursor=Dr.limit,J(),Dr.cursor=Dr.limit,nr&&(R(),Dr.cursor=Dr.limit_backward,er())))}};return function(r){return"function"==typeof r.update?r.update(function(r){return n.setCurrent(r),n.stem(),n.getCurrent()}):(n.setCurrent(r),n.stem(),n.getCurrent())}}(),r.Pipeline.registerFunction(r.tr.stemmer,"stemmer-tr"),r.tr.stopWordFilter=r.generateStopWordFilter("acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle".split(" ")),r.Pipeline.registerFunction(r.tr.stopWordFilter,"stopWordFilter-tr")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.vi.min.js b/assets/javascripts/lunr/min/lunr.vi.min.js new file mode 100644 index 000000000..22aed28c4 --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.vi.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/min/lunr.zh.min.js b/assets/javascripts/lunr/min/lunr.zh.min.js new file mode 100644 index 000000000..9838ef96d --- /dev/null +++ b/assets/javascripts/lunr/min/lunr.zh.min.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); \ No newline at end of file diff --git a/assets/javascripts/lunr/tinyseg.js b/assets/javascripts/lunr/tinyseg.js new file mode 100644 index 000000000..167fa6dd6 --- /dev/null +++ b/assets/javascripts/lunr/tinyseg.js @@ -0,0 +1,206 @@ +/** + * export the module via AMD, CommonJS or as a browser global + * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js + */ +;(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory) + } else if (typeof exports === 'object') { + /** + * Node. Does not work with strict CommonJS, but + * only CommonJS-like environments that support module.exports, + * like Node. + */ + module.exports = factory() + } else { + // Browser globals (root is window) + factory()(root.lunr); + } +}(this, function () { + /** + * Just return a value to define the module export. + * This example returns an object, but the module + * can return a function as the exported value. + */ + + return function(lunr) { + // TinySegmenter 0.1 -- Super compact Japanese tokenizer in Javascript + // (c) 2008 Taku Kudo + // TinySegmenter is freely distributable under the terms of a new BSD licence. + // For details, see http://chasen.org/~taku/software/TinySegmenter/LICENCE.txt + + function TinySegmenter() { + var patterns = { + "[一二三四五六七八九十百千万億兆]":"M", + "[一-龠々〆ヵヶ]":"H", + "[ぁ-ん]":"I", + "[ァ-ヴーア-ン゙ー]":"K", + "[a-zA-Za-zA-Z]":"A", + "[0-90-9]":"N" + } + this.chartype_ = []; + for (var i in patterns) { + var regexp = new RegExp(i); + this.chartype_.push([regexp, patterns[i]]); + } + + this.BIAS__ = -332 + this.BC1__ = {"HH":6,"II":2461,"KH":406,"OH":-1378}; + this.BC2__ = {"AA":-3267,"AI":2744,"AN":-878,"HH":-4070,"HM":-1711,"HN":4012,"HO":3761,"IA":1327,"IH":-1184,"II":-1332,"IK":1721,"IO":5492,"KI":3831,"KK":-8741,"MH":-3132,"MK":3334,"OO":-2920}; + this.BC3__ = {"HH":996,"HI":626,"HK":-721,"HN":-1307,"HO":-836,"IH":-301,"KK":2762,"MK":1079,"MM":4034,"OA":-1652,"OH":266}; + this.BP1__ = {"BB":295,"OB":304,"OO":-125,"UB":352}; + this.BP2__ = {"BO":60,"OO":-1762}; + this.BQ1__ = {"BHH":1150,"BHM":1521,"BII":-1158,"BIM":886,"BMH":1208,"BNH":449,"BOH":-91,"BOO":-2597,"OHI":451,"OIH":-296,"OKA":1851,"OKH":-1020,"OKK":904,"OOO":2965}; + this.BQ2__ = {"BHH":118,"BHI":-1159,"BHM":466,"BIH":-919,"BKK":-1720,"BKO":864,"OHH":-1139,"OHM":-181,"OIH":153,"UHI":-1146}; + this.BQ3__ = {"BHH":-792,"BHI":2664,"BII":-299,"BKI":419,"BMH":937,"BMM":8335,"BNN":998,"BOH":775,"OHH":2174,"OHM":439,"OII":280,"OKH":1798,"OKI":-793,"OKO":-2242,"OMH":-2402,"OOO":11699}; + this.BQ4__ = {"BHH":-3895,"BIH":3761,"BII":-4654,"BIK":1348,"BKK":-1806,"BMI":-3385,"BOO":-12396,"OAH":926,"OHH":266,"OHK":-2036,"ONN":-973}; + this.BW1__ = {",と":660,",同":727,"B1あ":1404,"B1同":542,"、と":660,"、同":727,"」と":1682,"あっ":1505,"いう":1743,"いっ":-2055,"いる":672,"うし":-4817,"うん":665,"から":3472,"がら":600,"こう":-790,"こと":2083,"こん":-1262,"さら":-4143,"さん":4573,"した":2641,"して":1104,"すで":-3399,"そこ":1977,"それ":-871,"たち":1122,"ため":601,"った":3463,"つい":-802,"てい":805,"てき":1249,"でき":1127,"です":3445,"では":844,"とい":-4915,"とみ":1922,"どこ":3887,"ない":5713,"なっ":3015,"など":7379,"なん":-1113,"にし":2468,"には":1498,"にも":1671,"に対":-912,"の一":-501,"の中":741,"ませ":2448,"まで":1711,"まま":2600,"まる":-2155,"やむ":-1947,"よっ":-2565,"れた":2369,"れで":-913,"をし":1860,"を見":731,"亡く":-1886,"京都":2558,"取り":-2784,"大き":-2604,"大阪":1497,"平方":-2314,"引き":-1336,"日本":-195,"本当":-2423,"毎日":-2113,"目指":-724,"B1あ":1404,"B1同":542,"」と":1682}; + this.BW2__ = {"..":-11822,"11":-669,"――":-5730,"−−":-13175,"いう":-1609,"うか":2490,"かし":-1350,"かも":-602,"から":-7194,"かれ":4612,"がい":853,"がら":-3198,"きた":1941,"くな":-1597,"こと":-8392,"この":-4193,"させ":4533,"され":13168,"さん":-3977,"しい":-1819,"しか":-545,"した":5078,"して":972,"しな":939,"その":-3744,"たい":-1253,"たた":-662,"ただ":-3857,"たち":-786,"たと":1224,"たは":-939,"った":4589,"って":1647,"っと":-2094,"てい":6144,"てき":3640,"てく":2551,"ては":-3110,"ても":-3065,"でい":2666,"でき":-1528,"でし":-3828,"です":-4761,"でも":-4203,"とい":1890,"とこ":-1746,"とと":-2279,"との":720,"とみ":5168,"とも":-3941,"ない":-2488,"なが":-1313,"など":-6509,"なの":2614,"なん":3099,"にお":-1615,"にし":2748,"にな":2454,"によ":-7236,"に対":-14943,"に従":-4688,"に関":-11388,"のか":2093,"ので":-7059,"のに":-6041,"のの":-6125,"はい":1073,"はが":-1033,"はず":-2532,"ばれ":1813,"まし":-1316,"まで":-6621,"まれ":5409,"めて":-3153,"もい":2230,"もの":-10713,"らか":-944,"らし":-1611,"らに":-1897,"りし":651,"りま":1620,"れた":4270,"れて":849,"れば":4114,"ろう":6067,"われ":7901,"を通":-11877,"んだ":728,"んな":-4115,"一人":602,"一方":-1375,"一日":970,"一部":-1051,"上が":-4479,"会社":-1116,"出て":2163,"分の":-7758,"同党":970,"同日":-913,"大阪":-2471,"委員":-1250,"少な":-1050,"年度":-8669,"年間":-1626,"府県":-2363,"手権":-1982,"新聞":-4066,"日新":-722,"日本":-7068,"日米":3372,"曜日":-601,"朝鮮":-2355,"本人":-2697,"東京":-1543,"然と":-1384,"社会":-1276,"立て":-990,"第に":-1612,"米国":-4268,"11":-669}; + this.BW3__ = {"あた":-2194,"あり":719,"ある":3846,"い.":-1185,"い。":-1185,"いい":5308,"いえ":2079,"いく":3029,"いた":2056,"いっ":1883,"いる":5600,"いわ":1527,"うち":1117,"うと":4798,"えと":1454,"か.":2857,"か。":2857,"かけ":-743,"かっ":-4098,"かに":-669,"から":6520,"かり":-2670,"が,":1816,"が、":1816,"がき":-4855,"がけ":-1127,"がっ":-913,"がら":-4977,"がり":-2064,"きた":1645,"けど":1374,"こと":7397,"この":1542,"ころ":-2757,"さい":-714,"さを":976,"し,":1557,"し、":1557,"しい":-3714,"した":3562,"して":1449,"しな":2608,"しま":1200,"す.":-1310,"す。":-1310,"する":6521,"ず,":3426,"ず、":3426,"ずに":841,"そう":428,"た.":8875,"た。":8875,"たい":-594,"たの":812,"たり":-1183,"たる":-853,"だ.":4098,"だ。":4098,"だっ":1004,"った":-4748,"って":300,"てい":6240,"てお":855,"ても":302,"です":1437,"でに":-1482,"では":2295,"とう":-1387,"とし":2266,"との":541,"とも":-3543,"どう":4664,"ない":1796,"なく":-903,"など":2135,"に,":-1021,"に、":-1021,"にし":1771,"にな":1906,"には":2644,"の,":-724,"の、":-724,"の子":-1000,"は,":1337,"は、":1337,"べき":2181,"まし":1113,"ます":6943,"まっ":-1549,"まで":6154,"まれ":-793,"らし":1479,"られ":6820,"るる":3818,"れ,":854,"れ、":854,"れた":1850,"れて":1375,"れば":-3246,"れる":1091,"われ":-605,"んだ":606,"んで":798,"カ月":990,"会議":860,"入り":1232,"大会":2217,"始め":1681,"市":965,"新聞":-5055,"日,":974,"日、":974,"社会":2024,"カ月":990}; + this.TC1__ = {"AAA":1093,"HHH":1029,"HHM":580,"HII":998,"HOH":-390,"HOM":-331,"IHI":1169,"IOH":-142,"IOI":-1015,"IOM":467,"MMH":187,"OOI":-1832}; + this.TC2__ = {"HHO":2088,"HII":-1023,"HMM":-1154,"IHI":-1965,"KKH":703,"OII":-2649}; + this.TC3__ = {"AAA":-294,"HHH":346,"HHI":-341,"HII":-1088,"HIK":731,"HOH":-1486,"IHH":128,"IHI":-3041,"IHO":-1935,"IIH":-825,"IIM":-1035,"IOI":-542,"KHH":-1216,"KKA":491,"KKH":-1217,"KOK":-1009,"MHH":-2694,"MHM":-457,"MHO":123,"MMH":-471,"NNH":-1689,"NNO":662,"OHO":-3393}; + this.TC4__ = {"HHH":-203,"HHI":1344,"HHK":365,"HHM":-122,"HHN":182,"HHO":669,"HIH":804,"HII":679,"HOH":446,"IHH":695,"IHO":-2324,"IIH":321,"III":1497,"IIO":656,"IOO":54,"KAK":4845,"KKA":3386,"KKK":3065,"MHH":-405,"MHI":201,"MMH":-241,"MMM":661,"MOM":841}; + this.TQ1__ = {"BHHH":-227,"BHHI":316,"BHIH":-132,"BIHH":60,"BIII":1595,"BNHH":-744,"BOHH":225,"BOOO":-908,"OAKK":482,"OHHH":281,"OHIH":249,"OIHI":200,"OIIH":-68}; + this.TQ2__ = {"BIHH":-1401,"BIII":-1033,"BKAK":-543,"BOOO":-5591}; + this.TQ3__ = {"BHHH":478,"BHHM":-1073,"BHIH":222,"BHII":-504,"BIIH":-116,"BIII":-105,"BMHI":-863,"BMHM":-464,"BOMH":620,"OHHH":346,"OHHI":1729,"OHII":997,"OHMH":481,"OIHH":623,"OIIH":1344,"OKAK":2792,"OKHH":587,"OKKA":679,"OOHH":110,"OOII":-685}; + this.TQ4__ = {"BHHH":-721,"BHHM":-3604,"BHII":-966,"BIIH":-607,"BIII":-2181,"OAAA":-2763,"OAKK":180,"OHHH":-294,"OHHI":2446,"OHHO":480,"OHIH":-1573,"OIHH":1935,"OIHI":-493,"OIIH":626,"OIII":-4007,"OKAK":-8156}; + this.TW1__ = {"につい":-4681,"東京都":2026}; + this.TW2__ = {"ある程":-2049,"いった":-1256,"ころが":-2434,"しょう":3873,"その後":-4430,"だって":-1049,"ていた":1833,"として":-4657,"ともに":-4517,"もので":1882,"一気に":-792,"初めて":-1512,"同時に":-8097,"大きな":-1255,"対して":-2721,"社会党":-3216}; + this.TW3__ = {"いただ":-1734,"してい":1314,"として":-4314,"につい":-5483,"にとっ":-5989,"に当た":-6247,"ので,":-727,"ので、":-727,"のもの":-600,"れから":-3752,"十二月":-2287}; + this.TW4__ = {"いう.":8576,"いう。":8576,"からな":-2348,"してい":2958,"たが,":1516,"たが、":1516,"ている":1538,"という":1349,"ました":5543,"ません":1097,"ようと":-4258,"よると":5865}; + this.UC1__ = {"A":484,"K":93,"M":645,"O":-505}; + this.UC2__ = {"A":819,"H":1059,"I":409,"M":3987,"N":5775,"O":646}; + this.UC3__ = {"A":-1370,"I":2311}; + this.UC4__ = {"A":-2643,"H":1809,"I":-1032,"K":-3450,"M":3565,"N":3876,"O":6646}; + this.UC5__ = {"H":313,"I":-1238,"K":-799,"M":539,"O":-831}; + this.UC6__ = {"H":-506,"I":-253,"K":87,"M":247,"O":-387}; + this.UP1__ = {"O":-214}; + this.UP2__ = {"B":69,"O":935}; + this.UP3__ = {"B":189}; + this.UQ1__ = {"BH":21,"BI":-12,"BK":-99,"BN":142,"BO":-56,"OH":-95,"OI":477,"OK":410,"OO":-2422}; + this.UQ2__ = {"BH":216,"BI":113,"OK":1759}; + this.UQ3__ = {"BA":-479,"BH":42,"BI":1913,"BK":-7198,"BM":3160,"BN":6427,"BO":14761,"OI":-827,"ON":-3212}; + this.UW1__ = {",":156,"、":156,"「":-463,"あ":-941,"う":-127,"が":-553,"き":121,"こ":505,"で":-201,"と":-547,"ど":-123,"に":-789,"の":-185,"は":-847,"も":-466,"や":-470,"よ":182,"ら":-292,"り":208,"れ":169,"を":-446,"ん":-137,"・":-135,"主":-402,"京":-268,"区":-912,"午":871,"国":-460,"大":561,"委":729,"市":-411,"日":-141,"理":361,"生":-408,"県":-386,"都":-718,"「":-463,"・":-135}; + this.UW2__ = {",":-829,"、":-829,"〇":892,"「":-645,"」":3145,"あ":-538,"い":505,"う":134,"お":-502,"か":1454,"が":-856,"く":-412,"こ":1141,"さ":878,"ざ":540,"し":1529,"す":-675,"せ":300,"そ":-1011,"た":188,"だ":1837,"つ":-949,"て":-291,"で":-268,"と":-981,"ど":1273,"な":1063,"に":-1764,"の":130,"は":-409,"ひ":-1273,"べ":1261,"ま":600,"も":-1263,"や":-402,"よ":1639,"り":-579,"る":-694,"れ":571,"を":-2516,"ん":2095,"ア":-587,"カ":306,"キ":568,"ッ":831,"三":-758,"不":-2150,"世":-302,"中":-968,"主":-861,"事":492,"人":-123,"会":978,"保":362,"入":548,"初":-3025,"副":-1566,"北":-3414,"区":-422,"大":-1769,"天":-865,"太":-483,"子":-1519,"学":760,"実":1023,"小":-2009,"市":-813,"年":-1060,"強":1067,"手":-1519,"揺":-1033,"政":1522,"文":-1355,"新":-1682,"日":-1815,"明":-1462,"最":-630,"朝":-1843,"本":-1650,"東":-931,"果":-665,"次":-2378,"民":-180,"気":-1740,"理":752,"発":529,"目":-1584,"相":-242,"県":-1165,"立":-763,"第":810,"米":509,"自":-1353,"行":838,"西":-744,"見":-3874,"調":1010,"議":1198,"込":3041,"開":1758,"間":-1257,"「":-645,"」":3145,"ッ":831,"ア":-587,"カ":306,"キ":568}; + this.UW3__ = {",":4889,"1":-800,"−":-1723,"、":4889,"々":-2311,"〇":5827,"」":2670,"〓":-3573,"あ":-2696,"い":1006,"う":2342,"え":1983,"お":-4864,"か":-1163,"が":3271,"く":1004,"け":388,"げ":401,"こ":-3552,"ご":-3116,"さ":-1058,"し":-395,"す":584,"せ":3685,"そ":-5228,"た":842,"ち":-521,"っ":-1444,"つ":-1081,"て":6167,"で":2318,"と":1691,"ど":-899,"な":-2788,"に":2745,"の":4056,"は":4555,"ひ":-2171,"ふ":-1798,"へ":1199,"ほ":-5516,"ま":-4384,"み":-120,"め":1205,"も":2323,"や":-788,"よ":-202,"ら":727,"り":649,"る":5905,"れ":2773,"わ":-1207,"を":6620,"ん":-518,"ア":551,"グ":1319,"ス":874,"ッ":-1350,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278,"・":-3794,"一":-1619,"下":-1759,"世":-2087,"両":3815,"中":653,"主":-758,"予":-1193,"二":974,"人":2742,"今":792,"他":1889,"以":-1368,"低":811,"何":4265,"作":-361,"保":-2439,"元":4858,"党":3593,"全":1574,"公":-3030,"六":755,"共":-1880,"円":5807,"再":3095,"分":457,"初":2475,"別":1129,"前":2286,"副":4437,"力":365,"動":-949,"務":-1872,"化":1327,"北":-1038,"区":4646,"千":-2309,"午":-783,"協":-1006,"口":483,"右":1233,"各":3588,"合":-241,"同":3906,"和":-837,"員":4513,"国":642,"型":1389,"場":1219,"外":-241,"妻":2016,"学":-1356,"安":-423,"実":-1008,"家":1078,"小":-513,"少":-3102,"州":1155,"市":3197,"平":-1804,"年":2416,"広":-1030,"府":1605,"度":1452,"建":-2352,"当":-3885,"得":1905,"思":-1291,"性":1822,"戸":-488,"指":-3973,"政":-2013,"教":-1479,"数":3222,"文":-1489,"新":1764,"日":2099,"旧":5792,"昨":-661,"時":-1248,"曜":-951,"最":-937,"月":4125,"期":360,"李":3094,"村":364,"東":-805,"核":5156,"森":2438,"業":484,"氏":2613,"民":-1694,"決":-1073,"法":1868,"海":-495,"無":979,"物":461,"特":-3850,"生":-273,"用":914,"町":1215,"的":7313,"直":-1835,"省":792,"県":6293,"知":-1528,"私":4231,"税":401,"立":-960,"第":1201,"米":7767,"系":3066,"約":3663,"級":1384,"統":-4229,"総":1163,"線":1255,"者":6457,"能":725,"自":-2869,"英":785,"見":1044,"調":-562,"財":-733,"費":1777,"車":1835,"軍":1375,"込":-1504,"通":-1136,"選":-681,"郎":1026,"郡":4404,"部":1200,"金":2163,"長":421,"開":-1432,"間":1302,"関":-1282,"雨":2009,"電":-1045,"非":2066,"駅":1620,"1":-800,"」":2670,"・":-3794,"ッ":-1350,"ア":551,"グ":1319,"ス":874,"ト":521,"ム":1109,"ル":1591,"ロ":2201,"ン":278}; + this.UW4__ = {",":3930,".":3508,"―":-4841,"、":3930,"。":3508,"〇":4999,"「":1895,"」":3798,"〓":-5156,"あ":4752,"い":-3435,"う":-640,"え":-2514,"お":2405,"か":530,"が":6006,"き":-4482,"ぎ":-3821,"く":-3788,"け":-4376,"げ":-4734,"こ":2255,"ご":1979,"さ":2864,"し":-843,"じ":-2506,"す":-731,"ず":1251,"せ":181,"そ":4091,"た":5034,"だ":5408,"ち":-3654,"っ":-5882,"つ":-1659,"て":3994,"で":7410,"と":4547,"な":5433,"に":6499,"ぬ":1853,"ね":1413,"の":7396,"は":8578,"ば":1940,"ひ":4249,"び":-4134,"ふ":1345,"へ":6665,"べ":-744,"ほ":1464,"ま":1051,"み":-2082,"む":-882,"め":-5046,"も":4169,"ゃ":-2666,"や":2795,"ょ":-1544,"よ":3351,"ら":-2922,"り":-9726,"る":-14896,"れ":-2613,"ろ":-4570,"わ":-1783,"を":13150,"ん":-2352,"カ":2145,"コ":1789,"セ":1287,"ッ":-724,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637,"・":-4371,"ー":-11870,"一":-2069,"中":2210,"予":782,"事":-190,"井":-1768,"人":1036,"以":544,"会":950,"体":-1286,"作":530,"側":4292,"先":601,"党":-2006,"共":-1212,"内":584,"円":788,"初":1347,"前":1623,"副":3879,"力":-302,"動":-740,"務":-2715,"化":776,"区":4517,"協":1013,"参":1555,"合":-1834,"和":-681,"員":-910,"器":-851,"回":1500,"国":-619,"園":-1200,"地":866,"場":-1410,"塁":-2094,"士":-1413,"多":1067,"大":571,"子":-4802,"学":-1397,"定":-1057,"寺":-809,"小":1910,"屋":-1328,"山":-1500,"島":-2056,"川":-2667,"市":2771,"年":374,"庁":-4556,"後":456,"性":553,"感":916,"所":-1566,"支":856,"改":787,"政":2182,"教":704,"文":522,"方":-856,"日":1798,"時":1829,"最":845,"月":-9066,"木":-485,"来":-442,"校":-360,"業":-1043,"氏":5388,"民":-2716,"気":-910,"沢":-939,"済":-543,"物":-735,"率":672,"球":-1267,"生":-1286,"産":-1101,"田":-2900,"町":1826,"的":2586,"目":922,"省":-3485,"県":2997,"空":-867,"立":-2112,"第":788,"米":2937,"系":786,"約":2171,"経":1146,"統":-1169,"総":940,"線":-994,"署":749,"者":2145,"能":-730,"般":-852,"行":-792,"規":792,"警":-1184,"議":-244,"谷":-1000,"賞":730,"車":-1481,"軍":1158,"輪":-1433,"込":-3370,"近":929,"道":-1291,"選":2596,"郎":-4866,"都":1192,"野":-1100,"銀":-2213,"長":357,"間":-2344,"院":-2297,"際":-2604,"電":-878,"領":-1659,"題":-792,"館":-1984,"首":1749,"高":2120,"「":1895,"」":3798,"・":-4371,"ッ":-724,"ー":-11870,"カ":2145,"コ":1789,"セ":1287,"ト":-403,"メ":-1635,"ラ":-881,"リ":-541,"ル":-856,"ン":-3637}; + this.UW5__ = {",":465,".":-299,"1":-514,"E2":-32768,"]":-2762,"、":465,"。":-299,"「":363,"あ":1655,"い":331,"う":-503,"え":1199,"お":527,"か":647,"が":-421,"き":1624,"ぎ":1971,"く":312,"げ":-983,"さ":-1537,"し":-1371,"す":-852,"だ":-1186,"ち":1093,"っ":52,"つ":921,"て":-18,"で":-850,"と":-127,"ど":1682,"な":-787,"に":-1224,"の":-635,"は":-578,"べ":1001,"み":502,"め":865,"ゃ":3350,"ょ":854,"り":-208,"る":429,"れ":504,"わ":419,"を":-1264,"ん":327,"イ":241,"ル":451,"ン":-343,"中":-871,"京":722,"会":-1153,"党":-654,"務":3519,"区":-901,"告":848,"員":2104,"大":-1296,"学":-548,"定":1785,"嵐":-1304,"市":-2991,"席":921,"年":1763,"思":872,"所":-814,"挙":1618,"新":-1682,"日":218,"月":-4353,"査":932,"格":1356,"機":-1508,"氏":-1347,"田":240,"町":-3912,"的":-3149,"相":1319,"省":-1052,"県":-4003,"研":-997,"社":-278,"空":-813,"統":1955,"者":-2233,"表":663,"語":-1073,"議":1219,"選":-1018,"郎":-368,"長":786,"間":1191,"題":2368,"館":-689,"1":-514,"E2":-32768,"「":363,"イ":241,"ル":451,"ン":-343}; + this.UW6__ = {",":227,".":808,"1":-270,"E1":306,"、":227,"。":808,"あ":-307,"う":189,"か":241,"が":-73,"く":-121,"こ":-200,"じ":1782,"す":383,"た":-428,"っ":573,"て":-1014,"で":101,"と":-105,"な":-253,"に":-149,"の":-417,"は":-236,"も":-206,"り":187,"る":-135,"を":195,"ル":-673,"ン":-496,"一":-277,"中":201,"件":-800,"会":624,"前":302,"区":1792,"員":-1212,"委":798,"学":-960,"市":887,"広":-695,"後":535,"業":-697,"相":753,"社":-507,"福":974,"空":-822,"者":1811,"連":463,"郎":1082,"1":-270,"E1":306,"ル":-673,"ン":-496}; + + return this; + } + TinySegmenter.prototype.ctype_ = function(str) { + for (var i in this.chartype_) { + if (str.match(this.chartype_[i][0])) { + return this.chartype_[i][1]; + } + } + return "O"; + } + + TinySegmenter.prototype.ts_ = function(v) { + if (v) { return v; } + return 0; + } + + TinySegmenter.prototype.segment = function(input) { + if (input == null || input == undefined || input == "") { + return []; + } + var result = []; + var seg = ["B3","B2","B1"]; + var ctype = ["O","O","O"]; + var o = input.split(""); + for (i = 0; i < o.length; ++i) { + seg.push(o[i]); + ctype.push(this.ctype_(o[i])) + } + seg.push("E1"); + seg.push("E2"); + seg.push("E3"); + ctype.push("O"); + ctype.push("O"); + ctype.push("O"); + var word = seg[3]; + var p1 = "U"; + var p2 = "U"; + var p3 = "U"; + for (var i = 4; i < seg.length - 3; ++i) { + var score = this.BIAS__; + var w1 = seg[i-3]; + var w2 = seg[i-2]; + var w3 = seg[i-1]; + var w4 = seg[i]; + var w5 = seg[i+1]; + var w6 = seg[i+2]; + var c1 = ctype[i-3]; + var c2 = ctype[i-2]; + var c3 = ctype[i-1]; + var c4 = ctype[i]; + var c5 = ctype[i+1]; + var c6 = ctype[i+2]; + score += this.ts_(this.UP1__[p1]); + score += this.ts_(this.UP2__[p2]); + score += this.ts_(this.UP3__[p3]); + score += this.ts_(this.BP1__[p1 + p2]); + score += this.ts_(this.BP2__[p2 + p3]); + score += this.ts_(this.UW1__[w1]); + score += this.ts_(this.UW2__[w2]); + score += this.ts_(this.UW3__[w3]); + score += this.ts_(this.UW4__[w4]); + score += this.ts_(this.UW5__[w5]); + score += this.ts_(this.UW6__[w6]); + score += this.ts_(this.BW1__[w2 + w3]); + score += this.ts_(this.BW2__[w3 + w4]); + score += this.ts_(this.BW3__[w4 + w5]); + score += this.ts_(this.TW1__[w1 + w2 + w3]); + score += this.ts_(this.TW2__[w2 + w3 + w4]); + score += this.ts_(this.TW3__[w3 + w4 + w5]); + score += this.ts_(this.TW4__[w4 + w5 + w6]); + score += this.ts_(this.UC1__[c1]); + score += this.ts_(this.UC2__[c2]); + score += this.ts_(this.UC3__[c3]); + score += this.ts_(this.UC4__[c4]); + score += this.ts_(this.UC5__[c5]); + score += this.ts_(this.UC6__[c6]); + score += this.ts_(this.BC1__[c2 + c3]); + score += this.ts_(this.BC2__[c3 + c4]); + score += this.ts_(this.BC3__[c4 + c5]); + score += this.ts_(this.TC1__[c1 + c2 + c3]); + score += this.ts_(this.TC2__[c2 + c3 + c4]); + score += this.ts_(this.TC3__[c3 + c4 + c5]); + score += this.ts_(this.TC4__[c4 + c5 + c6]); + // score += this.ts_(this.TC5__[c4 + c5 + c6]); + score += this.ts_(this.UQ1__[p1 + c1]); + score += this.ts_(this.UQ2__[p2 + c2]); + score += this.ts_(this.UQ3__[p3 + c3]); + score += this.ts_(this.BQ1__[p2 + c2 + c3]); + score += this.ts_(this.BQ2__[p2 + c3 + c4]); + score += this.ts_(this.BQ3__[p3 + c2 + c3]); + score += this.ts_(this.BQ4__[p3 + c3 + c4]); + score += this.ts_(this.TQ1__[p2 + c1 + c2 + c3]); + score += this.ts_(this.TQ2__[p2 + c2 + c3 + c4]); + score += this.ts_(this.TQ3__[p3 + c1 + c2 + c3]); + score += this.ts_(this.TQ4__[p3 + c2 + c3 + c4]); + var p = "O"; + if (score > 0) { + result.push(word); + word = ""; + p = "B"; + } + p1 = p2; + p2 = p3; + p3 = p; + word += seg[i]; + } + result.push(word); + + return result; + } + + lunr.TinySegmenter = TinySegmenter; + }; + +})); \ No newline at end of file diff --git a/assets/javascripts/lunr/wordcut.js b/assets/javascripts/lunr/wordcut.js new file mode 100644 index 000000000..146f4b44b --- /dev/null +++ b/assets/javascripts/lunr/wordcut.js @@ -0,0 +1,6708 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.lunr || (g.lunr = {})).wordcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1; + }) + this.addWords(words, false) + } + if(finalize){ + this.finalizeDict(); + } + }, + + dictSeek: function (l, r, ch, strOffset, pos) { + var ans = null; + while (l <= r) { + var m = Math.floor((l + r) / 2), + dict_item = this.dict[m], + len = dict_item.length; + if (len <= strOffset) { + l = m + 1; + } else { + var ch_ = dict_item[strOffset]; + if (ch_ < ch) { + l = m + 1; + } else if (ch_ > ch) { + r = m - 1; + } else { + ans = m; + if (pos == LEFT) { + r = m - 1; + } else { + l = m + 1; + } + } + } + } + return ans; + }, + + isFinal: function (acceptor) { + return this.dict[acceptor.l].length == acceptor.strOffset; + }, + + createAcceptor: function () { + return { + l: 0, + r: this.dict.length - 1, + strOffset: 0, + isFinal: false, + dict: this, + transit: function (ch) { + return this.dict.transit(this, ch); + }, + isError: false, + tag: "DICT", + w: 1, + type: "DICT" + }; + }, + + transit: function (acceptor, ch) { + var l = this.dictSeek(acceptor.l, + acceptor.r, + ch, + acceptor.strOffset, + LEFT); + if (l !== null) { + var r = this.dictSeek(l, + acceptor.r, + ch, + acceptor.strOffset, + RIGHT); + acceptor.l = l; + acceptor.r = r; + acceptor.strOffset++; + acceptor.isFinal = this.isFinal(acceptor); + } else { + acceptor.isError = true; + } + return acceptor; + }, + + sortuniq: function(a){ + return a.sort().filter(function(item, pos, arr){ + return !pos || item != arr[pos - 1]; + }) + }, + + flatten: function(a){ + //[[1,2],[3]] -> [1,2,3] + return [].concat.apply([], a); + } +}; +module.exports = WordcutDict; + +}).call(this,"/dist/tmp") +},{"glob":16,"path":22}],3:[function(require,module,exports){ +var WordRule = { + createAcceptor: function(tag) { + if (tag["WORD_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + var lch = ch.toLowerCase(); + if (lch >= "a" && lch <= "z") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "WORD_RULE", + type: "WORD_RULE", + w: 1}; + } +}; + +var NumberRule = { + createAcceptor: function(tag) { + if (tag["NUMBER_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch >= "0" && ch <= "9") { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "NUMBER_RULE", + type: "NUMBER_RULE", + w: 1}; + } +}; + +var SpaceRule = { + tag: "SPACE_RULE", + createAcceptor: function(tag) { + + if (tag["SPACE_RULE"]) + return null; + + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (ch == " " || ch == "\t" || ch == "\r" || ch == "\n" || + ch == "\u00A0" || ch=="\u2003"//nbsp and emsp + ) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: SpaceRule.tag, + w: 1, + type: "SPACE_RULE"}; + } +} + +var SingleSymbolRule = { + tag: "SINSYM", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) { + this.isFinal = true; + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "SINSYM", + w: 1, + type: "SINSYM"}; + } +} + + +var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule]; + +module.exports = LatinRules; + +},{}],4:[function(require,module,exports){ +var _ = require("underscore") + , WordcutCore = require("./wordcut_core"); +var PathInfoBuilder = { + + /* + buildByPartAcceptors: function(path, acceptors, i) { + var + var genInfos = partAcceptors.reduce(function(genInfos, acceptor) { + + }, []); + + return genInfos; + } + */ + + buildByAcceptors: function(path, finalAcceptors, i) { + var self = this; + var infos = finalAcceptors.map(function(acceptor) { + var p = i - acceptor.strOffset + 1 + , _info = path[p]; + + var info = {p: p, + mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw), + w: acceptor.w + _info.w, + unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk, + type: acceptor.type}; + + if (acceptor.type == "PART") { + for(var j = p + 1; j <= i; j++) { + path[j].merge = p; + } + info.merge = p; + } + + return info; + }); + return infos.filter(function(info) { return info; }); + }, + + fallback: function(path, leftBoundary, text, i) { + var _info = path[leftBoundary]; + if (text[i].match(/[\u0E48-\u0E4E]/)) { + if (leftBoundary != 0) + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + mw: 0, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; +/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") { + leftBoundary = path[leftBoundary].p; + return {p: leftBoundary, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; */ + } else { + return {p: leftBoundary, + mw: _info.mw, + w: 1 + _info.w, + unk: 1 + _info.unk, + type: "UNK"}; + } + }, + + build: function(path, finalAcceptors, i, leftBoundary, text) { + var basicPathInfos = this.buildByAcceptors(path, finalAcceptors, i); + if (basicPathInfos.length > 0) { + return basicPathInfos; + } else { + return [this.fallback(path, leftBoundary, text, i)]; + } + } +}; + +module.exports = function() { + return _.clone(PathInfoBuilder); +} + +},{"./wordcut_core":8,"underscore":25}],5:[function(require,module,exports){ +var _ = require("underscore"); + + +var PathSelector = { + selectPath: function(paths) { + var path = paths.reduce(function(selectedPath, path) { + if (selectedPath == null) { + return path; + } else { + if (path.unk < selectedPath.unk) + return path; + if (path.unk == selectedPath.unk) { + if (path.mw < selectedPath.mw) + return path + if (path.mw == selectedPath.mw) { + if (path.w < selectedPath.w) + return path; + } + } + return selectedPath; + } + }, null); + return path; + }, + + createPath: function() { + return [{p:null, w:0, unk:0, type: "INIT", mw:0}]; + } +}; + +module.exports = function() { + return _.clone(PathSelector); +}; + +},{"underscore":25}],6:[function(require,module,exports){ +function isMatch(pat, offset, ch) { + if (pat.length <= offset) + return false; + var _ch = pat[offset]; + return _ch == ch || + (_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) || + (_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/)); +} + +var Rule0 = { + pat: "เหก็ม", + createAcceptor: function(tag) { + return {strOffset: 0, + isFinal: false, + transit: function(ch) { + if (isMatch(Rule0.pat, this.strOffset,ch)) { + this.isFinal = (this.strOffset + 1 == Rule0.pat.length); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "THAI_RULE", + type: "THAI_RULE", + w: 1}; + } +}; + +var PartRule = { + createAcceptor: function(tag) { + return {strOffset: 0, + patterns: [ + "แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก" + ], + isFinal: false, + transit: function(ch) { + var offset = this.strOffset; + this.patterns = this.patterns.filter(function(pat) { + return isMatch(pat, offset, ch); + }); + + if (this.patterns.length > 0) { + var len = 1 + offset; + this.isFinal = this.patterns.some(function(pat) { + return pat.length == len; + }); + this.strOffset++; + } else { + this.isError = true; + } + return this; + }, + isError: false, + tag: "PART", + type: "PART", + unk: 1, + w: 1}; + } +}; + +var ThaiRules = [Rule0, PartRule]; + +module.exports = ThaiRules; + +},{}],7:[function(require,module,exports){ +var sys = require("sys") + , WordcutDict = require("./dict") + , WordcutCore = require("./wordcut_core") + , PathInfoBuilder = require("./path_info_builder") + , PathSelector = require("./path_selector") + , Acceptors = require("./acceptors") + , latinRules = require("./latin_rules") + , thaiRules = require("./thai_rules") + , _ = require("underscore"); + + +var Wordcut = Object.create(WordcutCore); +Wordcut.defaultPathInfoBuilder = PathInfoBuilder; +Wordcut.defaultPathSelector = PathSelector; +Wordcut.defaultAcceptors = Acceptors; +Wordcut.defaultLatinRules = latinRules; +Wordcut.defaultThaiRules = thaiRules; +Wordcut.defaultDict = WordcutDict; + + +Wordcut.initNoDict = function(dict_path) { + var self = this; + self.pathInfoBuilder = new self.defaultPathInfoBuilder; + self.pathSelector = new self.defaultPathSelector; + self.acceptors = new self.defaultAcceptors; + self.defaultLatinRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); + self.defaultThaiRules.forEach(function(rule) { + self.acceptors.creators.push(rule); + }); +}; + +Wordcut.init = function(dict_path, withDefault, additionalWords) { + withDefault = withDefault || false; + this.initNoDict(); + var dict = _.clone(this.defaultDict); + dict.init(dict_path, withDefault, additionalWords); + this.acceptors.creators.push(dict); +}; + +module.exports = Wordcut; + +},{"./acceptors":1,"./dict":2,"./latin_rules":3,"./path_info_builder":4,"./path_selector":5,"./thai_rules":6,"./wordcut_core":8,"sys":28,"underscore":25}],8:[function(require,module,exports){ +var WordcutCore = { + + buildPath: function(text) { + var self = this + , path = self.pathSelector.createPath() + , leftBoundary = 0; + self.acceptors.reset(); + for (var i = 0; i < text.length; i++) { + var ch = text[i]; + self.acceptors.transit(ch); + + var possiblePathInfos = self + .pathInfoBuilder + .build(path, + self.acceptors.getFinalAcceptors(), + i, + leftBoundary, + text); + var selectedPath = self.pathSelector.selectPath(possiblePathInfos) + + path.push(selectedPath); + if (selectedPath.type !== "UNK") { + leftBoundary = i; + } + } + return path; + }, + + pathToRanges: function(path) { + var e = path.length - 1 + , ranges = []; + + while (e > 0) { + var info = path[e] + , s = info.p; + + if (info.merge !== undefined && ranges.length > 0) { + var r = ranges[ranges.length - 1]; + r.s = info.merge; + s = r.s; + } else { + ranges.push({s:s, e:e}); + } + e = s; + } + return ranges.reverse(); + }, + + rangesToText: function(text, ranges, delimiter) { + return ranges.map(function(r) { + return text.substring(r.s, r.e); + }).join(delimiter); + }, + + cut: function(text, delimiter) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + return this + .rangesToText(text, ranges, + (delimiter === undefined ? "|" : delimiter)); + }, + + cutIntoRanges: function(text, noText) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + if (!noText) { + ranges.forEach(function(r) { + r.text = text.substring(r.s, r.e); + }); + } + return ranges; + }, + + cutIntoArray: function(text) { + var path = this.buildPath(text) + , ranges = this.pathToRanges(path); + + return ranges.map(function(r) { + return text.substring(r.s, r.e) + }); + } +}; + +module.exports = WordcutCore; + +},{}],9:[function(require,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// 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 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. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && !isFinite(value)) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) { + return a === b; + } + var aIsArgs = isArguments(a), + bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +},{"util/":28}],10:[function(require,module,exports){ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} + +},{}],11:[function(require,module,exports){ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + + +},{"balanced-match":10,"concat-map":13}],12:[function(require,module,exports){ + +},{}],13:[function(require,module,exports){ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +},{}],14:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],15:[function(require,module,exports){ +(function (process){ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern) + } + + return { + matcher: new Minimatch(pattern), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + // disable comments and negation unless the user explicitly + // passes in false as the option. + options.nonegate = options.nonegate === false ? false : true + options.nocomment = options.nocomment === false ? false : true + deprecationWarning(options) + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +// TODO(isaacs): remove entirely in v6 +// exported to reset in tests +exports.deprecationWarned +function deprecationWarning(options) { + if (!options.nonegate || !options.nocomment) { + if (process.noDeprecation !== true && !exports.deprecationWarned) { + var msg = 'glob WARNING: comments and negation will be disabled in v6' + if (process.throwDeprecation) + throw new Error(msg) + else if (process.traceDeprecation) + console.trace(msg) + else + console.error(msg) + + exports.deprecationWarned = true + } + } +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +}).call(this,require('_process')) +},{"_process":24,"minimatch":20,"path":22,"path-is-absolute":23}],16:[function(require,module,exports){ +(function (process){ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +glob.hasMagic = function (pattern, options_) { + var options = util._extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./sync.js":17,"_process":24,"assert":9,"events":14,"fs":12,"inflight":18,"inherits":19,"minimatch":20,"once":21,"path":22,"path-is-absolute":23,"util":28}],17:[function(require,module,exports){ +(function (process){ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +}).call(this,require('_process')) +},{"./common.js":15,"./glob.js":16,"_process":24,"assert":9,"fs":12,"minimatch":20,"path":22,"path-is-absolute":23,"util":28}],18:[function(require,module,exports){ +(function (process){ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} + +}).call(this,require('_process')) +},{"_process":24,"once":21,"wrappy":29}],19:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],20:[function(require,module,exports){ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = require('path') +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + // "" only matches "" + if (pattern.trim() === '') return p === '' + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } + + // should be unreachable. + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} + +},{"brace-expansion":11,"path":22}],21:[function(require,module,exports){ +var wrappy = require('wrappy') +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + +},{"wrappy":29}],22:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":24}],23:[function(require,module,exports){ +(function (process){ +'use strict'; + +function posix(path) { + return path.charAt(0) === '/'; +} + +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} + +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; + +}).call(this,require('_process')) +},{"_process":24}],24:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],25:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],26:[function(require,module,exports){ +arguments[4][19][0].apply(exports,arguments) +},{"dup":19}],27:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],28:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":27,"_process":24,"inherits":26}],29:[function(require,module,exports){ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + +},{}]},{},[7])(7) +}); \ No newline at end of file diff --git a/assets/javascripts/workers/search.16e2a7d4.min.js b/assets/javascripts/workers/search.16e2a7d4.min.js new file mode 100644 index 000000000..e0dc159e8 --- /dev/null +++ b/assets/javascripts/workers/search.16e2a7d4.min.js @@ -0,0 +1,48 @@ +"use strict";(()=>{var ge=Object.create;var W=Object.defineProperty,ye=Object.defineProperties,me=Object.getOwnPropertyDescriptor,ve=Object.getOwnPropertyDescriptors,xe=Object.getOwnPropertyNames,G=Object.getOwnPropertySymbols,Se=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty,Qe=Object.prototype.propertyIsEnumerable;var J=(t,e,r)=>e in t?W(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,M=(t,e)=>{for(var r in e||(e={}))X.call(e,r)&&J(t,r,e[r]);if(G)for(var r of G(e))Qe.call(e,r)&&J(t,r,e[r]);return t},Z=(t,e)=>ye(t,ve(e));var K=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var be=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of xe(e))!X.call(t,i)&&i!==r&&W(t,i,{get:()=>e[i],enumerable:!(n=me(e,i))||n.enumerable});return t};var H=(t,e,r)=>(r=t!=null?ge(Se(t)):{},be(e||!t||!t.__esModule?W(r,"default",{value:t,enumerable:!0}):r,t));var z=(t,e,r)=>new Promise((n,i)=>{var s=u=>{try{a(r.next(u))}catch(c){i(c)}},o=u=>{try{a(r.throw(u))}catch(c){i(c)}},a=u=>u.done?n(u.value):Promise.resolve(u.value).then(s,o);a((r=r.apply(t,e)).next())});var re=K((ee,te)=>{/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var h=t.utils.clone(r)||{};h.position=[a,c],h.index=s.length,s.push(new t.Token(n.slice(a,o),h))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ou?h+=2:a==u&&(r+=n[c+1]*i[h+1],c+=2,h+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}if(s.str.length==0&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var h=s.str.charAt(0),y=s.str.charAt(1),g;y in s.node.edges?g=s.node.edges[y]:(g=new t.TokenSet,s.node.edges[y]=g),s.str.length==1&&(g.final=!0),i.push({node:g,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof ee=="object"?te.exports=r():e.lunr=r()}(this,function(){return t})})()});var q=K((Re,ne)=>{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Le=/["'&<>]/;ne.exports=we;function we(t){var e=""+t,r=Le.exec(e);if(!r)return e;var n,i="",s=0,o=0;for(s=r.index;s=0;r--){let n=t[r];typeof n=="string"?n=document.createTextNode(n):n.parentNode&&n.parentNode.removeChild(n),r?e.insertBefore(this.previousSibling,n):e.replaceChild(n,this)}}}));var ie=H(q());function se(t){let e=new Map,r=new Set;for(let n of t){let[i,s]=n.location.split("#"),o=n.location,a=n.title,u=n.tags,c=(0,ie.default)(n.text).replace(/\s+(?=[,.:;!?])/g,"").replace(/\s+/g," ");if(s){let h=e.get(i);r.has(h)?e.set(o,{location:o,title:a,text:c,parent:h}):(h.title=n.title,h.text=c,r.add(h))}else e.set(o,M({location:o,title:a,text:c},u&&{tags:u}))}return e}var oe=H(q());function ae(t,e){let r=new RegExp(t.separator,"img"),n=(i,s,o)=>`${s}${o}`;return i=>{i=i.replace(/[\s*+\-:~^]+/g," ").trim();let s=new RegExp(`(^|${t.separator})(${i.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return o=>(e?(0,oe.default)(o):o).replace(s,n).replace(/<\/mark>(\s+)]*>/img,"$1")}}function ue(t){let e=new lunr.Query(["title","text"]);return new lunr.QueryParser(t,e).parse(),e.clauses}function ce(t,e){var i;let r=new Set(t),n={};for(let s=0;s!n.has(i)))]}var U=class{constructor({config:e,docs:r,options:n}){this.options=n,this.documents=se(r),this.highlight=ae(e,!1),lunr.tokenizer.separator=new RegExp(e.separator),this.index=lunr(function(){e.lang.length===1&&e.lang[0]!=="en"?this.use(lunr[e.lang[0]]):e.lang.length>1&&this.use(lunr.multiLanguage(...e.lang));let i=Ee(["trimmer","stopWordFilter","stemmer"],n.pipeline);for(let s of e.lang.map(o=>o==="en"?lunr:lunr[o]))for(let o of i)this.pipeline.remove(s[o]),this.searchPipeline.remove(s[o]);this.ref("location"),this.field("title",{boost:1e3}),this.field("text"),this.field("tags",{boost:1e6,extractor:s=>{let{tags:o=[]}=s;return o.reduce((a,u)=>[...a,...lunr.tokenizer(u)],[])}});for(let s of r)this.add(s,{boost:s.boost})})}search(e){if(e)try{let r=this.highlight(e),n=ue(e).filter(o=>o.presence!==lunr.Query.presence.PROHIBITED),i=this.index.search(`${e}*`).reduce((o,{ref:a,score:u,matchData:c})=>{let h=this.documents.get(a);if(typeof h!="undefined"){let{location:y,title:g,text:b,tags:m,parent:Q}=h,p=ce(n,Object.keys(c.metadata)),d=+!Q+ +Object.values(p).every(w=>w);o.push(Z(M({location:y,title:r(g),text:r(b)},m&&{tags:m.map(r)}),{score:u*(1+d),terms:p}))}return o},[]).sort((o,a)=>a.score-o.score).reduce((o,a)=>{let u=this.documents.get(a.location);if(typeof u!="undefined"){let c="parent"in u?u.parent.location:u.location;o.set(c,[...o.get(c)||[],a])}return o},new Map),s;if(this.options.suggestions){let o=this.index.query(a=>{for(let u of n)a.term(u.term,{fields:["title"],presence:lunr.Query.presence.REQUIRED,wildcard:lunr.Query.wildcard.TRAILING})});s=o.length?Object.keys(o[0].matchData.metadata):[]}return M({items:[...i.values()]},typeof s!="undefined"&&{suggestions:s})}catch(r){console.warn(`Invalid query: ${e} \u2013 see https://bit.ly/2s3ChXG`)}return{items:[]}}};var Y;function ke(t){return z(this,null,function*(){let e="../lunr";if(typeof parent!="undefined"&&"IFrameWorker"in parent){let n=document.querySelector("script[src]"),[i]=n.src.split("/worker");e=e.replace("..",i)}let r=[];for(let n of t.lang){switch(n){case"ja":r.push(`${e}/tinyseg.js`);break;case"hi":case"th":r.push(`${e}/wordcut.js`);break}n!=="en"&&r.push(`${e}/min/lunr.${n}.min.js`)}t.lang.length>1&&r.push(`${e}/min/lunr.multi.min.js`),r.length&&(yield importScripts(`${e}/min/lunr.stemmer.support.min.js`,...r))})}function Te(t){return z(this,null,function*(){switch(t.type){case 0:return yield ke(t.data.config),Y=new U(t.data),{type:1};case 2:return{type:3,data:Y?Y.search(t.data):{items:[]}};default:throw new TypeError("Invalid message type")}})}self.lunr=le.default;addEventListener("message",t=>z(void 0,null,function*(){postMessage(yield Te(t.data))}));})(); +//# sourceMappingURL=search.16e2a7d4.min.js.map + diff --git a/assets/javascripts/workers/search.16e2a7d4.min.js.map b/assets/javascripts/workers/search.16e2a7d4.min.js.map new file mode 100644 index 000000000..fa01f3742 --- /dev/null +++ b/assets/javascripts/workers/search.16e2a7d4.min.js.map @@ -0,0 +1,8 @@ +{ + "version": 3, + "sources": ["node_modules/lunr/lunr.js", "node_modules/escape-html/index.js", "src/assets/javascripts/integrations/search/worker/main/index.ts", "src/assets/javascripts/polyfills/index.ts", "src/assets/javascripts/integrations/search/document/index.ts", "src/assets/javascripts/integrations/search/highlighter/index.ts", "src/assets/javascripts/integrations/search/query/_/index.ts", "src/assets/javascripts/integrations/search/_/index.ts"], + "sourceRoot": "../../../..", + "sourcesContent": ["/**\n * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9\n * Copyright (C) 2020 Oliver Nightingale\n * @license MIT\n */\n\n;(function(){\n\n/**\n * A convenience function for configuring and constructing\n * a new lunr Index.\n *\n * A lunr.Builder instance is created and the pipeline setup\n * with a trimmer, stop word filter and stemmer.\n *\n * This builder object is yielded to the configuration function\n * that is passed as a parameter, allowing the list of fields\n * and other builder parameters to be customised.\n *\n * All documents _must_ be added within the passed config function.\n *\n * @example\n * var idx = lunr(function () {\n * this.field('title')\n * this.field('body')\n * this.ref('id')\n *\n * documents.forEach(function (doc) {\n * this.add(doc)\n * }, this)\n * })\n *\n * @see {@link lunr.Builder}\n * @see {@link lunr.Pipeline}\n * @see {@link lunr.trimmer}\n * @see {@link lunr.stopWordFilter}\n * @see {@link lunr.stemmer}\n * @namespace {function} lunr\n */\nvar lunr = function (config) {\n var builder = new lunr.Builder\n\n builder.pipeline.add(\n lunr.trimmer,\n lunr.stopWordFilter,\n lunr.stemmer\n )\n\n builder.searchPipeline.add(\n lunr.stemmer\n )\n\n config.call(builder, builder)\n return builder.build()\n}\n\nlunr.version = \"2.3.9\"\n/*!\n * lunr.utils\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A namespace containing utils for the rest of the lunr library\n * @namespace lunr.utils\n */\nlunr.utils = {}\n\n/**\n * Print a warning message to the console.\n *\n * @param {String} message The message to be printed.\n * @memberOf lunr.utils\n * @function\n */\nlunr.utils.warn = (function (global) {\n /* eslint-disable no-console */\n return function (message) {\n if (global.console && console.warn) {\n console.warn(message)\n }\n }\n /* eslint-enable no-console */\n})(this)\n\n/**\n * Convert an object to a string.\n *\n * In the case of `null` and `undefined` the function returns\n * the empty string, in all other cases the result of calling\n * `toString` on the passed object is returned.\n *\n * @param {Any} obj The object to convert to a string.\n * @return {String} string representation of the passed object.\n * @memberOf lunr.utils\n */\nlunr.utils.asString = function (obj) {\n if (obj === void 0 || obj === null) {\n return \"\"\n } else {\n return obj.toString()\n }\n}\n\n/**\n * Clones an object.\n *\n * Will create a copy of an existing object such that any mutations\n * on the copy cannot affect the original.\n *\n * Only shallow objects are supported, passing a nested object to this\n * function will cause a TypeError.\n *\n * Objects with primitives, and arrays of primitives are supported.\n *\n * @param {Object} obj The object to clone.\n * @return {Object} a clone of the passed object.\n * @throws {TypeError} when a nested object is passed.\n * @memberOf Utils\n */\nlunr.utils.clone = function (obj) {\n if (obj === null || obj === undefined) {\n return obj\n }\n\n var clone = Object.create(null),\n keys = Object.keys(obj)\n\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i],\n val = obj[key]\n\n if (Array.isArray(val)) {\n clone[key] = val.slice()\n continue\n }\n\n if (typeof val === 'string' ||\n typeof val === 'number' ||\n typeof val === 'boolean') {\n clone[key] = val\n continue\n }\n\n throw new TypeError(\"clone is not deep and does not support nested objects\")\n }\n\n return clone\n}\nlunr.FieldRef = function (docRef, fieldName, stringValue) {\n this.docRef = docRef\n this.fieldName = fieldName\n this._stringValue = stringValue\n}\n\nlunr.FieldRef.joiner = \"/\"\n\nlunr.FieldRef.fromString = function (s) {\n var n = s.indexOf(lunr.FieldRef.joiner)\n\n if (n === -1) {\n throw \"malformed field ref string\"\n }\n\n var fieldRef = s.slice(0, n),\n docRef = s.slice(n + 1)\n\n return new lunr.FieldRef (docRef, fieldRef, s)\n}\n\nlunr.FieldRef.prototype.toString = function () {\n if (this._stringValue == undefined) {\n this._stringValue = this.fieldName + lunr.FieldRef.joiner + this.docRef\n }\n\n return this._stringValue\n}\n/*!\n * lunr.Set\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A lunr set.\n *\n * @constructor\n */\nlunr.Set = function (elements) {\n this.elements = Object.create(null)\n\n if (elements) {\n this.length = elements.length\n\n for (var i = 0; i < this.length; i++) {\n this.elements[elements[i]] = true\n }\n } else {\n this.length = 0\n }\n}\n\n/**\n * A complete set that contains all elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.complete = {\n intersect: function (other) {\n return other\n },\n\n union: function () {\n return this\n },\n\n contains: function () {\n return true\n }\n}\n\n/**\n * An empty set that contains no elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.empty = {\n intersect: function () {\n return this\n },\n\n union: function (other) {\n return other\n },\n\n contains: function () {\n return false\n }\n}\n\n/**\n * Returns true if this set contains the specified object.\n *\n * @param {object} object - Object whose presence in this set is to be tested.\n * @returns {boolean} - True if this set contains the specified object.\n */\nlunr.Set.prototype.contains = function (object) {\n return !!this.elements[object]\n}\n\n/**\n * Returns a new set containing only the elements that are present in both\n * this set and the specified set.\n *\n * @param {lunr.Set} other - set to intersect with this set.\n * @returns {lunr.Set} a new set that is the intersection of this and the specified set.\n */\n\nlunr.Set.prototype.intersect = function (other) {\n var a, b, elements, intersection = []\n\n if (other === lunr.Set.complete) {\n return this\n }\n\n if (other === lunr.Set.empty) {\n return other\n }\n\n if (this.length < other.length) {\n a = this\n b = other\n } else {\n a = other\n b = this\n }\n\n elements = Object.keys(a.elements)\n\n for (var i = 0; i < elements.length; i++) {\n var element = elements[i]\n if (element in b.elements) {\n intersection.push(element)\n }\n }\n\n return new lunr.Set (intersection)\n}\n\n/**\n * Returns a new set combining the elements of this and the specified set.\n *\n * @param {lunr.Set} other - set to union with this set.\n * @return {lunr.Set} a new set that is the union of this and the specified set.\n */\n\nlunr.Set.prototype.union = function (other) {\n if (other === lunr.Set.complete) {\n return lunr.Set.complete\n }\n\n if (other === lunr.Set.empty) {\n return this\n }\n\n return new lunr.Set(Object.keys(this.elements).concat(Object.keys(other.elements)))\n}\n/**\n * A function to calculate the inverse document frequency for\n * a posting. This is shared between the builder and the index\n *\n * @private\n * @param {object} posting - The posting for a given term\n * @param {number} documentCount - The total number of documents.\n */\nlunr.idf = function (posting, documentCount) {\n var documentsWithTerm = 0\n\n for (var fieldName in posting) {\n if (fieldName == '_index') continue // Ignore the term index, its not a field\n documentsWithTerm += Object.keys(posting[fieldName]).length\n }\n\n var x = (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5)\n\n return Math.log(1 + Math.abs(x))\n}\n\n/**\n * A token wraps a string representation of a token\n * as it is passed through the text processing pipeline.\n *\n * @constructor\n * @param {string} [str=''] - The string token being wrapped.\n * @param {object} [metadata={}] - Metadata associated with this token.\n */\nlunr.Token = function (str, metadata) {\n this.str = str || \"\"\n this.metadata = metadata || {}\n}\n\n/**\n * Returns the token string that is being wrapped by this object.\n *\n * @returns {string}\n */\nlunr.Token.prototype.toString = function () {\n return this.str\n}\n\n/**\n * A token update function is used when updating or optionally\n * when cloning a token.\n *\n * @callback lunr.Token~updateFunction\n * @param {string} str - The string representation of the token.\n * @param {Object} metadata - All metadata associated with this token.\n */\n\n/**\n * Applies the given function to the wrapped string token.\n *\n * @example\n * token.update(function (str, metadata) {\n * return str.toUpperCase()\n * })\n *\n * @param {lunr.Token~updateFunction} fn - A function to apply to the token string.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.update = function (fn) {\n this.str = fn(this.str, this.metadata)\n return this\n}\n\n/**\n * Creates a clone of this token. Optionally a function can be\n * applied to the cloned token.\n *\n * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.clone = function (fn) {\n fn = fn || function (s) { return s }\n return new lunr.Token (fn(this.str, this.metadata), this.metadata)\n}\n/*!\n * lunr.tokenizer\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A function for splitting a string into tokens ready to be inserted into\n * the search index. Uses `lunr.tokenizer.separator` to split strings, change\n * the value of this property to change how strings are split into tokens.\n *\n * This tokenizer will convert its parameter to a string by calling `toString` and\n * then will split this string on the character in `lunr.tokenizer.separator`.\n * Arrays will have their elements converted to strings and wrapped in a lunr.Token.\n *\n * Optional metadata can be passed to the tokenizer, this metadata will be cloned and\n * added as metadata to every token that is created from the object to be tokenized.\n *\n * @static\n * @param {?(string|object|object[])} obj - The object to convert into tokens\n * @param {?object} metadata - Optional metadata to associate with every token\n * @returns {lunr.Token[]}\n * @see {@link lunr.Pipeline}\n */\nlunr.tokenizer = function (obj, metadata) {\n if (obj == null || obj == undefined) {\n return []\n }\n\n if (Array.isArray(obj)) {\n return obj.map(function (t) {\n return new lunr.Token(\n lunr.utils.asString(t).toLowerCase(),\n lunr.utils.clone(metadata)\n )\n })\n }\n\n var str = obj.toString().toLowerCase(),\n len = str.length,\n tokens = []\n\n for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) {\n var char = str.charAt(sliceEnd),\n sliceLength = sliceEnd - sliceStart\n\n if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) {\n\n if (sliceLength > 0) {\n var tokenMetadata = lunr.utils.clone(metadata) || {}\n tokenMetadata[\"position\"] = [sliceStart, sliceLength]\n tokenMetadata[\"index\"] = tokens.length\n\n tokens.push(\n new lunr.Token (\n str.slice(sliceStart, sliceEnd),\n tokenMetadata\n )\n )\n }\n\n sliceStart = sliceEnd + 1\n }\n\n }\n\n return tokens\n}\n\n/**\n * The separator used to split a string into tokens. Override this property to change the behaviour of\n * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens.\n *\n * @static\n * @see lunr.tokenizer\n */\nlunr.tokenizer.separator = /[\\s\\-]+/\n/*!\n * lunr.Pipeline\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.Pipelines maintain an ordered list of functions to be applied to all\n * tokens in documents entering the search index and queries being ran against\n * the index.\n *\n * An instance of lunr.Index created with the lunr shortcut will contain a\n * pipeline with a stop word filter and an English language stemmer. Extra\n * functions can be added before or after either of these functions or these\n * default functions can be removed.\n *\n * When run the pipeline will call each function in turn, passing a token, the\n * index of that token in the original list of all tokens and finally a list of\n * all the original tokens.\n *\n * The output of functions in the pipeline will be passed to the next function\n * in the pipeline. To exclude a token from entering the index the function\n * should return undefined, the rest of the pipeline will not be called with\n * this token.\n *\n * For serialisation of pipelines to work, all functions used in an instance of\n * a pipeline should be registered with lunr.Pipeline. Registered functions can\n * then be loaded. If trying to load a serialised pipeline that uses functions\n * that are not registered an error will be thrown.\n *\n * If not planning on serialising the pipeline then registering pipeline functions\n * is not necessary.\n *\n * @constructor\n */\nlunr.Pipeline = function () {\n this._stack = []\n}\n\nlunr.Pipeline.registeredFunctions = Object.create(null)\n\n/**\n * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token\n * string as well as all known metadata. A pipeline function can mutate the token string\n * or mutate (or add) metadata for a given token.\n *\n * A pipeline function can indicate that the passed token should be discarded by returning\n * null, undefined or an empty string. This token will not be passed to any downstream pipeline\n * functions and will not be added to the index.\n *\n * Multiple tokens can be returned by returning an array of tokens. Each token will be passed\n * to any downstream pipeline functions and all will returned tokens will be added to the index.\n *\n * Any number of pipeline functions may be chained together using a lunr.Pipeline.\n *\n * @interface lunr.PipelineFunction\n * @param {lunr.Token} token - A token from the document being processed.\n * @param {number} i - The index of this token in the complete list of tokens for this document/field.\n * @param {lunr.Token[]} tokens - All tokens for this document/field.\n * @returns {(?lunr.Token|lunr.Token[])}\n */\n\n/**\n * Register a function with the pipeline.\n *\n * Functions that are used in the pipeline should be registered if the pipeline\n * needs to be serialised, or a serialised pipeline needs to be loaded.\n *\n * Registering a function does not add it to a pipeline, functions must still be\n * added to instances of the pipeline for them to be used when running a pipeline.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @param {String} label - The label to register this function with\n */\nlunr.Pipeline.registerFunction = function (fn, label) {\n if (label in this.registeredFunctions) {\n lunr.utils.warn('Overwriting existing registered function: ' + label)\n }\n\n fn.label = label\n lunr.Pipeline.registeredFunctions[fn.label] = fn\n}\n\n/**\n * Warns if the function is not registered as a Pipeline function.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @private\n */\nlunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {\n var isRegistered = fn.label && (fn.label in this.registeredFunctions)\n\n if (!isRegistered) {\n lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\\n', fn)\n }\n}\n\n/**\n * Loads a previously serialised pipeline.\n *\n * All functions to be loaded must already be registered with lunr.Pipeline.\n * If any function from the serialised data has not been registered then an\n * error will be thrown.\n *\n * @param {Object} serialised - The serialised pipeline to load.\n * @returns {lunr.Pipeline}\n */\nlunr.Pipeline.load = function (serialised) {\n var pipeline = new lunr.Pipeline\n\n serialised.forEach(function (fnName) {\n var fn = lunr.Pipeline.registeredFunctions[fnName]\n\n if (fn) {\n pipeline.add(fn)\n } else {\n throw new Error('Cannot load unregistered function: ' + fnName)\n }\n })\n\n return pipeline\n}\n\n/**\n * Adds new functions to the end of the pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline.\n */\nlunr.Pipeline.prototype.add = function () {\n var fns = Array.prototype.slice.call(arguments)\n\n fns.forEach(function (fn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n this._stack.push(fn)\n }, this)\n}\n\n/**\n * Adds a single function after a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.after = function (existingFn, newFn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n var pos = this._stack.indexOf(existingFn)\n if (pos == -1) {\n throw new Error('Cannot find existingFn')\n }\n\n pos = pos + 1\n this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Adds a single function before a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.before = function (existingFn, newFn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n var pos = this._stack.indexOf(existingFn)\n if (pos == -1) {\n throw new Error('Cannot find existingFn')\n }\n\n this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Removes a function from the pipeline.\n *\n * @param {lunr.PipelineFunction} fn The function to remove from the pipeline.\n */\nlunr.Pipeline.prototype.remove = function (fn) {\n var pos = this._stack.indexOf(fn)\n if (pos == -1) {\n return\n }\n\n this._stack.splice(pos, 1)\n}\n\n/**\n * Runs the current list of functions that make up the pipeline against the\n * passed tokens.\n *\n * @param {Array} tokens The tokens to run through the pipeline.\n * @returns {Array}\n */\nlunr.Pipeline.prototype.run = function (tokens) {\n var stackLength = this._stack.length\n\n for (var i = 0; i < stackLength; i++) {\n var fn = this._stack[i]\n var memo = []\n\n for (var j = 0; j < tokens.length; j++) {\n var result = fn(tokens[j], j, tokens)\n\n if (result === null || result === void 0 || result === '') continue\n\n if (Array.isArray(result)) {\n for (var k = 0; k < result.length; k++) {\n memo.push(result[k])\n }\n } else {\n memo.push(result)\n }\n }\n\n tokens = memo\n }\n\n return tokens\n}\n\n/**\n * Convenience method for passing a string through a pipeline and getting\n * strings out. This method takes care of wrapping the passed string in a\n * token and mapping the resulting tokens back to strings.\n *\n * @param {string} str - The string to pass through the pipeline.\n * @param {?object} metadata - Optional metadata to associate with the token\n * passed to the pipeline.\n * @returns {string[]}\n */\nlunr.Pipeline.prototype.runString = function (str, metadata) {\n var token = new lunr.Token (str, metadata)\n\n return this.run([token]).map(function (t) {\n return t.toString()\n })\n}\n\n/**\n * Resets the pipeline by removing any existing processors.\n *\n */\nlunr.Pipeline.prototype.reset = function () {\n this._stack = []\n}\n\n/**\n * Returns a representation of the pipeline ready for serialisation.\n *\n * Logs a warning if the function has not been registered.\n *\n * @returns {Array}\n */\nlunr.Pipeline.prototype.toJSON = function () {\n return this._stack.map(function (fn) {\n lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n\n return fn.label\n })\n}\n/*!\n * lunr.Vector\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A vector is used to construct the vector space of documents and queries. These\n * vectors support operations to determine the similarity between two documents or\n * a document and a query.\n *\n * Normally no parameters are required for initializing a vector, but in the case of\n * loading a previously dumped vector the raw elements can be provided to the constructor.\n *\n * For performance reasons vectors are implemented with a flat array, where an elements\n * index is immediately followed by its value. E.g. [index, value, index, value]. This\n * allows the underlying array to be as sparse as possible and still offer decent\n * performance when being used for vector calculations.\n *\n * @constructor\n * @param {Number[]} [elements] - The flat list of element index and element value pairs.\n */\nlunr.Vector = function (elements) {\n this._magnitude = 0\n this.elements = elements || []\n}\n\n\n/**\n * Calculates the position within the vector to insert a given index.\n *\n * This is used internally by insert and upsert. If there are duplicate indexes then\n * the position is returned as if the value for that index were to be updated, but it\n * is the callers responsibility to check whether there is a duplicate at that index\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @returns {Number}\n */\nlunr.Vector.prototype.positionForIndex = function (index) {\n // For an empty vector the tuple can be inserted at the beginning\n if (this.elements.length == 0) {\n return 0\n }\n\n var start = 0,\n end = this.elements.length / 2,\n sliceLength = end - start,\n pivotPoint = Math.floor(sliceLength / 2),\n pivotIndex = this.elements[pivotPoint * 2]\n\n while (sliceLength > 1) {\n if (pivotIndex < index) {\n start = pivotPoint\n }\n\n if (pivotIndex > index) {\n end = pivotPoint\n }\n\n if (pivotIndex == index) {\n break\n }\n\n sliceLength = end - start\n pivotPoint = start + Math.floor(sliceLength / 2)\n pivotIndex = this.elements[pivotPoint * 2]\n }\n\n if (pivotIndex == index) {\n return pivotPoint * 2\n }\n\n if (pivotIndex > index) {\n return pivotPoint * 2\n }\n\n if (pivotIndex < index) {\n return (pivotPoint + 1) * 2\n }\n}\n\n/**\n * Inserts an element at an index within the vector.\n *\n * Does not allow duplicates, will throw an error if there is already an entry\n * for this index.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n */\nlunr.Vector.prototype.insert = function (insertIdx, val) {\n this.upsert(insertIdx, val, function () {\n throw \"duplicate index\"\n })\n}\n\n/**\n * Inserts or updates an existing index within the vector.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n * @param {function} fn - A function that is called for updates, the existing value and the\n * requested value are passed as arguments\n */\nlunr.Vector.prototype.upsert = function (insertIdx, val, fn) {\n this._magnitude = 0\n var position = this.positionForIndex(insertIdx)\n\n if (this.elements[position] == insertIdx) {\n this.elements[position + 1] = fn(this.elements[position + 1], val)\n } else {\n this.elements.splice(position, 0, insertIdx, val)\n }\n}\n\n/**\n * Calculates the magnitude of this vector.\n *\n * @returns {Number}\n */\nlunr.Vector.prototype.magnitude = function () {\n if (this._magnitude) return this._magnitude\n\n var sumOfSquares = 0,\n elementsLength = this.elements.length\n\n for (var i = 1; i < elementsLength; i += 2) {\n var val = this.elements[i]\n sumOfSquares += val * val\n }\n\n return this._magnitude = Math.sqrt(sumOfSquares)\n}\n\n/**\n * Calculates the dot product of this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The vector to compute the dot product with.\n * @returns {Number}\n */\nlunr.Vector.prototype.dot = function (otherVector) {\n var dotProduct = 0,\n a = this.elements, b = otherVector.elements,\n aLen = a.length, bLen = b.length,\n aVal = 0, bVal = 0,\n i = 0, j = 0\n\n while (i < aLen && j < bLen) {\n aVal = a[i], bVal = b[j]\n if (aVal < bVal) {\n i += 2\n } else if (aVal > bVal) {\n j += 2\n } else if (aVal == bVal) {\n dotProduct += a[i + 1] * b[j + 1]\n i += 2\n j += 2\n }\n }\n\n return dotProduct\n}\n\n/**\n * Calculates the similarity between this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The other vector to calculate the\n * similarity with.\n * @returns {Number}\n */\nlunr.Vector.prototype.similarity = function (otherVector) {\n return this.dot(otherVector) / this.magnitude() || 0\n}\n\n/**\n * Converts the vector to an array of the elements within the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toArray = function () {\n var output = new Array (this.elements.length / 2)\n\n for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) {\n output[j] = this.elements[i]\n }\n\n return output\n}\n\n/**\n * A JSON serializable representation of the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toJSON = function () {\n return this.elements\n}\n/* eslint-disable */\n/*!\n * lunr.stemmer\n * Copyright (C) 2020 Oliver Nightingale\n * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n */\n\n/**\n * lunr.stemmer is an english language stemmer, this is a JavaScript\n * implementation of the PorterStemmer taken from http://tartarus.org/~martin\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token - The string to stem\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n * @function\n */\nlunr.stemmer = (function(){\n var step2list = {\n \"ational\" : \"ate\",\n \"tional\" : \"tion\",\n \"enci\" : \"ence\",\n \"anci\" : \"ance\",\n \"izer\" : \"ize\",\n \"bli\" : \"ble\",\n \"alli\" : \"al\",\n \"entli\" : \"ent\",\n \"eli\" : \"e\",\n \"ousli\" : \"ous\",\n \"ization\" : \"ize\",\n \"ation\" : \"ate\",\n \"ator\" : \"ate\",\n \"alism\" : \"al\",\n \"iveness\" : \"ive\",\n \"fulness\" : \"ful\",\n \"ousness\" : \"ous\",\n \"aliti\" : \"al\",\n \"iviti\" : \"ive\",\n \"biliti\" : \"ble\",\n \"logi\" : \"log\"\n },\n\n step3list = {\n \"icate\" : \"ic\",\n \"ative\" : \"\",\n \"alize\" : \"al\",\n \"iciti\" : \"ic\",\n \"ical\" : \"ic\",\n \"ful\" : \"\",\n \"ness\" : \"\"\n },\n\n c = \"[^aeiou]\", // consonant\n v = \"[aeiouy]\", // vowel\n C = c + \"[^aeiouy]*\", // consonant sequence\n V = v + \"[aeiou]*\", // vowel sequence\n\n mgr0 = \"^(\" + C + \")?\" + V + C, // [C]VC... is m>0\n meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\", // [C]VC[V] is m=1\n mgr1 = \"^(\" + C + \")?\" + V + C + V + C, // [C]VCVC... is m>1\n s_v = \"^(\" + C + \")?\" + v; // vowel in stem\n\n var re_mgr0 = new RegExp(mgr0);\n var re_mgr1 = new RegExp(mgr1);\n var re_meq1 = new RegExp(meq1);\n var re_s_v = new RegExp(s_v);\n\n var re_1a = /^(.+?)(ss|i)es$/;\n var re2_1a = /^(.+?)([^s])s$/;\n var re_1b = /^(.+?)eed$/;\n var re2_1b = /^(.+?)(ed|ing)$/;\n var re_1b_2 = /.$/;\n var re2_1b_2 = /(at|bl|iz)$/;\n var re3_1b_2 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n var re4_1b_2 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var re_1c = /^(.+?[^aeiou])y$/;\n var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n\n var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n\n var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n var re2_4 = /^(.+?)(s|t)(ion)$/;\n\n var re_5 = /^(.+?)e$/;\n var re_5_1 = /ll$/;\n var re3_5 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n var porterStemmer = function porterStemmer(w) {\n var stem,\n suffix,\n firstch,\n re,\n re2,\n re3,\n re4;\n\n if (w.length < 3) { return w; }\n\n firstch = w.substr(0,1);\n if (firstch == \"y\") {\n w = firstch.toUpperCase() + w.substr(1);\n }\n\n // Step 1a\n re = re_1a\n re2 = re2_1a;\n\n if (re.test(w)) { w = w.replace(re,\"$1$2\"); }\n else if (re2.test(w)) { w = w.replace(re2,\"$1$2\"); }\n\n // Step 1b\n re = re_1b;\n re2 = re2_1b;\n if (re.test(w)) {\n var fp = re.exec(w);\n re = re_mgr0;\n if (re.test(fp[1])) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1];\n re2 = re_s_v;\n if (re2.test(stem)) {\n w = stem;\n re2 = re2_1b_2;\n re3 = re3_1b_2;\n re4 = re4_1b_2;\n if (re2.test(w)) { w = w + \"e\"; }\n else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,\"\"); }\n else if (re4.test(w)) { w = w + \"e\"; }\n }\n }\n\n // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)\n re = re_1c;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n w = stem + \"i\";\n }\n\n // Step 2\n re = re_2;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step2list[suffix];\n }\n }\n\n // Step 3\n re = re_3;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n suffix = fp[2];\n re = re_mgr0;\n if (re.test(stem)) {\n w = stem + step3list[suffix];\n }\n }\n\n // Step 4\n re = re_4;\n re2 = re2_4;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n if (re.test(stem)) {\n w = stem;\n }\n } else if (re2.test(w)) {\n var fp = re2.exec(w);\n stem = fp[1] + fp[2];\n re2 = re_mgr1;\n if (re2.test(stem)) {\n w = stem;\n }\n }\n\n // Step 5\n re = re_5;\n if (re.test(w)) {\n var fp = re.exec(w);\n stem = fp[1];\n re = re_mgr1;\n re2 = re_meq1;\n re3 = re3_5;\n if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {\n w = stem;\n }\n }\n\n re = re_5_1;\n re2 = re_mgr1;\n if (re.test(w) && re2.test(w)) {\n re = re_1b_2;\n w = w.replace(re,\"\");\n }\n\n // and turn initial Y back to y\n\n if (firstch == \"y\") {\n w = firstch.toLowerCase() + w.substr(1);\n }\n\n return w;\n };\n\n return function (token) {\n return token.update(porterStemmer);\n }\n})();\n\nlunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')\n/*!\n * lunr.stopWordFilter\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.generateStopWordFilter builds a stopWordFilter function from the provided\n * list of stop words.\n *\n * The built in lunr.stopWordFilter is built using this generator and can be used\n * to generate custom stopWordFilters for applications or non English languages.\n *\n * @function\n * @param {Array} token The token to pass through the filter\n * @returns {lunr.PipelineFunction}\n * @see lunr.Pipeline\n * @see lunr.stopWordFilter\n */\nlunr.generateStopWordFilter = function (stopWords) {\n var words = stopWords.reduce(function (memo, stopWord) {\n memo[stopWord] = stopWord\n return memo\n }, {})\n\n return function (token) {\n if (token && words[token.toString()] !== token.toString()) return token\n }\n}\n\n/**\n * lunr.stopWordFilter is an English language stop word list filter, any words\n * contained in the list will not be passed through the filter.\n *\n * This is intended to be used in the Pipeline. If the token does not pass the\n * filter then undefined will be returned.\n *\n * @function\n * @implements {lunr.PipelineFunction}\n * @params {lunr.Token} token - A token to check for being a stop word.\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n */\nlunr.stopWordFilter = lunr.generateStopWordFilter([\n 'a',\n 'able',\n 'about',\n 'across',\n 'after',\n 'all',\n 'almost',\n 'also',\n 'am',\n 'among',\n 'an',\n 'and',\n 'any',\n 'are',\n 'as',\n 'at',\n 'be',\n 'because',\n 'been',\n 'but',\n 'by',\n 'can',\n 'cannot',\n 'could',\n 'dear',\n 'did',\n 'do',\n 'does',\n 'either',\n 'else',\n 'ever',\n 'every',\n 'for',\n 'from',\n 'get',\n 'got',\n 'had',\n 'has',\n 'have',\n 'he',\n 'her',\n 'hers',\n 'him',\n 'his',\n 'how',\n 'however',\n 'i',\n 'if',\n 'in',\n 'into',\n 'is',\n 'it',\n 'its',\n 'just',\n 'least',\n 'let',\n 'like',\n 'likely',\n 'may',\n 'me',\n 'might',\n 'most',\n 'must',\n 'my',\n 'neither',\n 'no',\n 'nor',\n 'not',\n 'of',\n 'off',\n 'often',\n 'on',\n 'only',\n 'or',\n 'other',\n 'our',\n 'own',\n 'rather',\n 'said',\n 'say',\n 'says',\n 'she',\n 'should',\n 'since',\n 'so',\n 'some',\n 'than',\n 'that',\n 'the',\n 'their',\n 'them',\n 'then',\n 'there',\n 'these',\n 'they',\n 'this',\n 'tis',\n 'to',\n 'too',\n 'twas',\n 'us',\n 'wants',\n 'was',\n 'we',\n 'were',\n 'what',\n 'when',\n 'where',\n 'which',\n 'while',\n 'who',\n 'whom',\n 'why',\n 'will',\n 'with',\n 'would',\n 'yet',\n 'you',\n 'your'\n])\n\nlunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')\n/*!\n * lunr.trimmer\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.trimmer is a pipeline function for trimming non word\n * characters from the beginning and end of tokens before they\n * enter the index.\n *\n * This implementation may not work correctly for non latin\n * characters and should either be removed or adapted for use\n * with languages with non-latin characters.\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token The token to pass through the filter\n * @returns {lunr.Token}\n * @see lunr.Pipeline\n */\nlunr.trimmer = function (token) {\n return token.update(function (s) {\n return s.replace(/^\\W+/, '').replace(/\\W+$/, '')\n })\n}\n\nlunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')\n/*!\n * lunr.TokenSet\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * A token set is used to store the unique list of all tokens\n * within an index. Token sets are also used to represent an\n * incoming query to the index, this query token set and index\n * token set are then intersected to find which tokens to look\n * up in the inverted index.\n *\n * A token set can hold multiple tokens, as in the case of the\n * index token set, or it can hold a single token as in the\n * case of a simple query token set.\n *\n * Additionally token sets are used to perform wildcard matching.\n * Leading, contained and trailing wildcards are supported, and\n * from this edit distance matching can also be provided.\n *\n * Token sets are implemented as a minimal finite state automata,\n * where both common prefixes and suffixes are shared between tokens.\n * This helps to reduce the space used for storing the token set.\n *\n * @constructor\n */\nlunr.TokenSet = function () {\n this.final = false\n this.edges = {}\n this.id = lunr.TokenSet._nextId\n lunr.TokenSet._nextId += 1\n}\n\n/**\n * Keeps track of the next, auto increment, identifier to assign\n * to a new tokenSet.\n *\n * TokenSets require a unique identifier to be correctly minimised.\n *\n * @private\n */\nlunr.TokenSet._nextId = 1\n\n/**\n * Creates a TokenSet instance from the given sorted array of words.\n *\n * @param {String[]} arr - A sorted array of strings to create the set from.\n * @returns {lunr.TokenSet}\n * @throws Will throw an error if the input array is not sorted.\n */\nlunr.TokenSet.fromArray = function (arr) {\n var builder = new lunr.TokenSet.Builder\n\n for (var i = 0, len = arr.length; i < len; i++) {\n builder.insert(arr[i])\n }\n\n builder.finish()\n return builder.root\n}\n\n/**\n * Creates a token set from a query clause.\n *\n * @private\n * @param {Object} clause - A single clause from lunr.Query.\n * @param {string} clause.term - The query clause term.\n * @param {number} [clause.editDistance] - The optional edit distance for the term.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromClause = function (clause) {\n if ('editDistance' in clause) {\n return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance)\n } else {\n return lunr.TokenSet.fromString(clause.term)\n }\n}\n\n/**\n * Creates a token set representing a single string with a specified\n * edit distance.\n *\n * Insertions, deletions, substitutions and transpositions are each\n * treated as an edit distance of 1.\n *\n * Increasing the allowed edit distance will have a dramatic impact\n * on the performance of both creating and intersecting these TokenSets.\n * It is advised to keep the edit distance less than 3.\n *\n * @param {string} str - The string to create the token set from.\n * @param {number} editDistance - The allowed edit distance to match.\n * @returns {lunr.Vector}\n */\nlunr.TokenSet.fromFuzzyString = function (str, editDistance) {\n var root = new lunr.TokenSet\n\n var stack = [{\n node: root,\n editsRemaining: editDistance,\n str: str\n }]\n\n while (stack.length) {\n var frame = stack.pop()\n\n // no edit\n if (frame.str.length > 0) {\n var char = frame.str.charAt(0),\n noEditNode\n\n if (char in frame.node.edges) {\n noEditNode = frame.node.edges[char]\n } else {\n noEditNode = new lunr.TokenSet\n frame.node.edges[char] = noEditNode\n }\n\n if (frame.str.length == 1) {\n noEditNode.final = true\n }\n\n stack.push({\n node: noEditNode,\n editsRemaining: frame.editsRemaining,\n str: frame.str.slice(1)\n })\n }\n\n if (frame.editsRemaining == 0) {\n continue\n }\n\n // insertion\n if (\"*\" in frame.node.edges) {\n var insertionNode = frame.node.edges[\"*\"]\n } else {\n var insertionNode = new lunr.TokenSet\n frame.node.edges[\"*\"] = insertionNode\n }\n\n if (frame.str.length == 0) {\n insertionNode.final = true\n }\n\n stack.push({\n node: insertionNode,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str\n })\n\n // deletion\n // can only do a deletion if we have enough edits remaining\n // and if there are characters left to delete in the string\n if (frame.str.length > 1) {\n stack.push({\n node: frame.node,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str.slice(1)\n })\n }\n\n // deletion\n // just removing the last character from the str\n if (frame.str.length == 1) {\n frame.node.final = true\n }\n\n // substitution\n // can only do a substitution if we have enough edits remaining\n // and if there are characters left to substitute\n if (frame.str.length >= 1) {\n if (\"*\" in frame.node.edges) {\n var substitutionNode = frame.node.edges[\"*\"]\n } else {\n var substitutionNode = new lunr.TokenSet\n frame.node.edges[\"*\"] = substitutionNode\n }\n\n if (frame.str.length == 1) {\n substitutionNode.final = true\n }\n\n stack.push({\n node: substitutionNode,\n editsRemaining: frame.editsRemaining - 1,\n str: frame.str.slice(1)\n })\n }\n\n // transposition\n // can only do a transposition if there are edits remaining\n // and there are enough characters to transpose\n if (frame.str.length > 1) {\n var charA = frame.str.charAt(0),\n charB = frame.str.charAt(1),\n transposeNode\n\n if (charB in frame.node.edges) {\n transposeNode = frame.node.edges[charB]\n } else {\n transposeNode = new lunr.TokenSet\n frame.node.edges[charB] = transposeNode\n }\n\n if (frame.str.length == 1) {\n transposeNode.final = true\n }\n\n stack.push({\n node: transposeNode,\n editsRemaining: frame.editsRemaining - 1,\n str: charA + frame.str.slice(2)\n })\n }\n }\n\n return root\n}\n\n/**\n * Creates a TokenSet from a string.\n *\n * The string may contain one or more wildcard characters (*)\n * that will allow wildcard matching when intersecting with\n * another TokenSet.\n *\n * @param {string} str - The string to create a TokenSet from.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromString = function (str) {\n var node = new lunr.TokenSet,\n root = node\n\n /*\n * Iterates through all characters within the passed string\n * appending a node for each character.\n *\n * When a wildcard character is found then a self\n * referencing edge is introduced to continually match\n * any number of any characters.\n */\n for (var i = 0, len = str.length; i < len; i++) {\n var char = str[i],\n final = (i == len - 1)\n\n if (char == \"*\") {\n node.edges[char] = node\n node.final = final\n\n } else {\n var next = new lunr.TokenSet\n next.final = final\n\n node.edges[char] = next\n node = next\n }\n }\n\n return root\n}\n\n/**\n * Converts this TokenSet into an array of strings\n * contained within the TokenSet.\n *\n * This is not intended to be used on a TokenSet that\n * contains wildcards, in these cases the results are\n * undefined and are likely to cause an infinite loop.\n *\n * @returns {string[]}\n */\nlunr.TokenSet.prototype.toArray = function () {\n var words = []\n\n var stack = [{\n prefix: \"\",\n node: this\n }]\n\n while (stack.length) {\n var frame = stack.pop(),\n edges = Object.keys(frame.node.edges),\n len = edges.length\n\n if (frame.node.final) {\n /* In Safari, at this point the prefix is sometimes corrupted, see:\n * https://github.com/olivernn/lunr.js/issues/279 Calling any\n * String.prototype method forces Safari to \"cast\" this string to what\n * it's supposed to be, fixing the bug. */\n frame.prefix.charAt(0)\n words.push(frame.prefix)\n }\n\n for (var i = 0; i < len; i++) {\n var edge = edges[i]\n\n stack.push({\n prefix: frame.prefix.concat(edge),\n node: frame.node.edges[edge]\n })\n }\n }\n\n return words\n}\n\n/**\n * Generates a string representation of a TokenSet.\n *\n * This is intended to allow TokenSets to be used as keys\n * in objects, largely to aid the construction and minimisation\n * of a TokenSet. As such it is not designed to be a human\n * friendly representation of the TokenSet.\n *\n * @returns {string}\n */\nlunr.TokenSet.prototype.toString = function () {\n // NOTE: Using Object.keys here as this.edges is very likely\n // to enter 'hash-mode' with many keys being added\n //\n // avoiding a for-in loop here as it leads to the function\n // being de-optimised (at least in V8). From some simple\n // benchmarks the performance is comparable, but allowing\n // V8 to optimize may mean easy performance wins in the future.\n\n if (this._str) {\n return this._str\n }\n\n var str = this.final ? '1' : '0',\n labels = Object.keys(this.edges).sort(),\n len = labels.length\n\n for (var i = 0; i < len; i++) {\n var label = labels[i],\n node = this.edges[label]\n\n str = str + label + node.id\n }\n\n return str\n}\n\n/**\n * Returns a new TokenSet that is the intersection of\n * this TokenSet and the passed TokenSet.\n *\n * This intersection will take into account any wildcards\n * contained within the TokenSet.\n *\n * @param {lunr.TokenSet} b - An other TokenSet to intersect with.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.prototype.intersect = function (b) {\n var output = new lunr.TokenSet,\n frame = undefined\n\n var stack = [{\n qNode: b,\n output: output,\n node: this\n }]\n\n while (stack.length) {\n frame = stack.pop()\n\n // NOTE: As with the #toString method, we are using\n // Object.keys and a for loop instead of a for-in loop\n // as both of these objects enter 'hash' mode, causing\n // the function to be de-optimised in V8\n var qEdges = Object.keys(frame.qNode.edges),\n qLen = qEdges.length,\n nEdges = Object.keys(frame.node.edges),\n nLen = nEdges.length\n\n for (var q = 0; q < qLen; q++) {\n var qEdge = qEdges[q]\n\n for (var n = 0; n < nLen; n++) {\n var nEdge = nEdges[n]\n\n if (nEdge == qEdge || qEdge == '*') {\n var node = frame.node.edges[nEdge],\n qNode = frame.qNode.edges[qEdge],\n final = node.final && qNode.final,\n next = undefined\n\n if (nEdge in frame.output.edges) {\n // an edge already exists for this character\n // no need to create a new node, just set the finality\n // bit unless this node is already final\n next = frame.output.edges[nEdge]\n next.final = next.final || final\n\n } else {\n // no edge exists yet, must create one\n // set the finality bit and insert it\n // into the output\n next = new lunr.TokenSet\n next.final = final\n frame.output.edges[nEdge] = next\n }\n\n stack.push({\n qNode: qNode,\n output: next,\n node: node\n })\n }\n }\n }\n }\n\n return output\n}\nlunr.TokenSet.Builder = function () {\n this.previousWord = \"\"\n this.root = new lunr.TokenSet\n this.uncheckedNodes = []\n this.minimizedNodes = {}\n}\n\nlunr.TokenSet.Builder.prototype.insert = function (word) {\n var node,\n commonPrefix = 0\n\n if (word < this.previousWord) {\n throw new Error (\"Out of order word insertion\")\n }\n\n for (var i = 0; i < word.length && i < this.previousWord.length; i++) {\n if (word[i] != this.previousWord[i]) break\n commonPrefix++\n }\n\n this.minimize(commonPrefix)\n\n if (this.uncheckedNodes.length == 0) {\n node = this.root\n } else {\n node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child\n }\n\n for (var i = commonPrefix; i < word.length; i++) {\n var nextNode = new lunr.TokenSet,\n char = word[i]\n\n node.edges[char] = nextNode\n\n this.uncheckedNodes.push({\n parent: node,\n char: char,\n child: nextNode\n })\n\n node = nextNode\n }\n\n node.final = true\n this.previousWord = word\n}\n\nlunr.TokenSet.Builder.prototype.finish = function () {\n this.minimize(0)\n}\n\nlunr.TokenSet.Builder.prototype.minimize = function (downTo) {\n for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) {\n var node = this.uncheckedNodes[i],\n childKey = node.child.toString()\n\n if (childKey in this.minimizedNodes) {\n node.parent.edges[node.char] = this.minimizedNodes[childKey]\n } else {\n // Cache the key for this node since\n // we know it can't change anymore\n node.child._str = childKey\n\n this.minimizedNodes[childKey] = node.child\n }\n\n this.uncheckedNodes.pop()\n }\n}\n/*!\n * lunr.Index\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * An index contains the built index of all documents and provides a query interface\n * to the index.\n *\n * Usually instances of lunr.Index will not be created using this constructor, instead\n * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be\n * used to load previously built and serialized indexes.\n *\n * @constructor\n * @param {Object} attrs - The attributes of the built search index.\n * @param {Object} attrs.invertedIndex - An index of term/field to document reference.\n * @param {Object} attrs.fieldVectors - Field vectors\n * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens.\n * @param {string[]} attrs.fields - The names of indexed document fields.\n * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms.\n */\nlunr.Index = function (attrs) {\n this.invertedIndex = attrs.invertedIndex\n this.fieldVectors = attrs.fieldVectors\n this.tokenSet = attrs.tokenSet\n this.fields = attrs.fields\n this.pipeline = attrs.pipeline\n}\n\n/**\n * A result contains details of a document matching a search query.\n * @typedef {Object} lunr.Index~Result\n * @property {string} ref - The reference of the document this result represents.\n * @property {number} score - A number between 0 and 1 representing how similar this document is to the query.\n * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match.\n */\n\n/**\n * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple\n * query language which itself is parsed into an instance of lunr.Query.\n *\n * For programmatically building queries it is advised to directly use lunr.Query, the query language\n * is best used for human entered text rather than program generated text.\n *\n * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported\n * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello'\n * or 'world', though those that contain both will rank higher in the results.\n *\n * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can\n * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding\n * wildcards will increase the number of documents that will be found but can also have a negative\n * impact on query performance, especially with wildcards at the beginning of a term.\n *\n * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term\n * hello in the title field will match this query. Using a field not present in the index will lead\n * to an error being thrown.\n *\n * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term\n * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported\n * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2.\n * Avoid large values for edit distance to improve query performance.\n *\n * Each term also supports a presence modifier. By default a term's presence in document is optional, however\n * this can be changed to either required or prohibited. For a term's presence to be required in a document the\n * term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and\n * optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not\n * appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'.\n *\n * To escape special characters the backslash character '\\' can be used, this allows searches to include\n * characters that would normally be considered modifiers, e.g. `foo\\~2` will search for a term \"foo~2\" instead\n * of attempting to apply a boost of 2 to the search term \"foo\".\n *\n * @typedef {string} lunr.Index~QueryString\n * @example Simple single term query\n * hello\n * @example Multiple term query\n * hello world\n * @example term scoped to a field\n * title:hello\n * @example term with a boost of 10\n * hello^10\n * @example term with an edit distance of 2\n * hello~2\n * @example terms with presence modifiers\n * -foo +bar baz\n */\n\n/**\n * Performs a search against the index using lunr query syntax.\n *\n * Results will be returned sorted by their score, the most relevant results\n * will be returned first. For details on how the score is calculated, please see\n * the {@link https://lunrjs.com/guides/searching.html#scoring|guide}.\n *\n * For more programmatic querying use lunr.Index#query.\n *\n * @param {lunr.Index~QueryString} queryString - A string containing a lunr query.\n * @throws {lunr.QueryParseError} If the passed query string cannot be parsed.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.search = function (queryString) {\n return this.query(function (query) {\n var parser = new lunr.QueryParser(queryString, query)\n parser.parse()\n })\n}\n\n/**\n * A query builder callback provides a query object to be used to express\n * the query to perform on the index.\n *\n * @callback lunr.Index~queryBuilder\n * @param {lunr.Query} query - The query object to build up.\n * @this lunr.Query\n */\n\n/**\n * Performs a query against the index using the yielded lunr.Query object.\n *\n * If performing programmatic queries against the index, this method is preferred\n * over lunr.Index#search so as to avoid the additional query parsing overhead.\n *\n * A query object is yielded to the supplied function which should be used to\n * express the query to be run against the index.\n *\n * Note that although this function takes a callback parameter it is _not_ an\n * asynchronous operation, the callback is just yielded a query object to be\n * customized.\n *\n * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.query = function (fn) {\n // for each query clause\n // * process terms\n // * expand terms from token set\n // * find matching documents and metadata\n // * get document vectors\n // * score documents\n\n var query = new lunr.Query(this.fields),\n matchingFields = Object.create(null),\n queryVectors = Object.create(null),\n termFieldCache = Object.create(null),\n requiredMatches = Object.create(null),\n prohibitedMatches = Object.create(null)\n\n /*\n * To support field level boosts a query vector is created per\n * field. An empty vector is eagerly created to support negated\n * queries.\n */\n for (var i = 0; i < this.fields.length; i++) {\n queryVectors[this.fields[i]] = new lunr.Vector\n }\n\n fn.call(query, query)\n\n for (var i = 0; i < query.clauses.length; i++) {\n /*\n * Unless the pipeline has been disabled for this term, which is\n * the case for terms with wildcards, we need to pass the clause\n * term through the search pipeline. A pipeline returns an array\n * of processed terms. Pipeline functions may expand the passed\n * term, which means we may end up performing multiple index lookups\n * for a single query term.\n */\n var clause = query.clauses[i],\n terms = null,\n clauseMatches = lunr.Set.empty\n\n if (clause.usePipeline) {\n terms = this.pipeline.runString(clause.term, {\n fields: clause.fields\n })\n } else {\n terms = [clause.term]\n }\n\n for (var m = 0; m < terms.length; m++) {\n var term = terms[m]\n\n /*\n * Each term returned from the pipeline needs to use the same query\n * clause object, e.g. the same boost and or edit distance. The\n * simplest way to do this is to re-use the clause object but mutate\n * its term property.\n */\n clause.term = term\n\n /*\n * From the term in the clause we create a token set which will then\n * be used to intersect the indexes token set to get a list of terms\n * to lookup in the inverted index\n */\n var termTokenSet = lunr.TokenSet.fromClause(clause),\n expandedTerms = this.tokenSet.intersect(termTokenSet).toArray()\n\n /*\n * If a term marked as required does not exist in the tokenSet it is\n * impossible for the search to return any matches. We set all the field\n * scoped required matches set to empty and stop examining any further\n * clauses.\n */\n if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) {\n for (var k = 0; k < clause.fields.length; k++) {\n var field = clause.fields[k]\n requiredMatches[field] = lunr.Set.empty\n }\n\n break\n }\n\n for (var j = 0; j < expandedTerms.length; j++) {\n /*\n * For each term get the posting and termIndex, this is required for\n * building the query vector.\n */\n var expandedTerm = expandedTerms[j],\n posting = this.invertedIndex[expandedTerm],\n termIndex = posting._index\n\n for (var k = 0; k < clause.fields.length; k++) {\n /*\n * For each field that this query term is scoped by (by default\n * all fields are in scope) we need to get all the document refs\n * that have this term in that field.\n *\n * The posting is the entry in the invertedIndex for the matching\n * term from above.\n */\n var field = clause.fields[k],\n fieldPosting = posting[field],\n matchingDocumentRefs = Object.keys(fieldPosting),\n termField = expandedTerm + \"/\" + field,\n matchingDocumentsSet = new lunr.Set(matchingDocumentRefs)\n\n /*\n * if the presence of this term is required ensure that the matching\n * documents are added to the set of required matches for this clause.\n *\n */\n if (clause.presence == lunr.Query.presence.REQUIRED) {\n clauseMatches = clauseMatches.union(matchingDocumentsSet)\n\n if (requiredMatches[field] === undefined) {\n requiredMatches[field] = lunr.Set.complete\n }\n }\n\n /*\n * if the presence of this term is prohibited ensure that the matching\n * documents are added to the set of prohibited matches for this field,\n * creating that set if it does not yet exist.\n */\n if (clause.presence == lunr.Query.presence.PROHIBITED) {\n if (prohibitedMatches[field] === undefined) {\n prohibitedMatches[field] = lunr.Set.empty\n }\n\n prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet)\n\n /*\n * Prohibited matches should not be part of the query vector used for\n * similarity scoring and no metadata should be extracted so we continue\n * to the next field\n */\n continue\n }\n\n /*\n * The query field vector is populated using the termIndex found for\n * the term and a unit value with the appropriate boost applied.\n * Using upsert because there could already be an entry in the vector\n * for the term we are working with. In that case we just add the scores\n * together.\n */\n queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b })\n\n /**\n * If we've already seen this term, field combo then we've already collected\n * the matching documents and metadata, no need to go through all that again\n */\n if (termFieldCache[termField]) {\n continue\n }\n\n for (var l = 0; l < matchingDocumentRefs.length; l++) {\n /*\n * All metadata for this term/field/document triple\n * are then extracted and collected into an instance\n * of lunr.MatchData ready to be returned in the query\n * results\n */\n var matchingDocumentRef = matchingDocumentRefs[l],\n matchingFieldRef = new lunr.FieldRef (matchingDocumentRef, field),\n metadata = fieldPosting[matchingDocumentRef],\n fieldMatch\n\n if ((fieldMatch = matchingFields[matchingFieldRef]) === undefined) {\n matchingFields[matchingFieldRef] = new lunr.MatchData (expandedTerm, field, metadata)\n } else {\n fieldMatch.add(expandedTerm, field, metadata)\n }\n\n }\n\n termFieldCache[termField] = true\n }\n }\n }\n\n /**\n * If the presence was required we need to update the requiredMatches field sets.\n * We do this after all fields for the term have collected their matches because\n * the clause terms presence is required in _any_ of the fields not _all_ of the\n * fields.\n */\n if (clause.presence === lunr.Query.presence.REQUIRED) {\n for (var k = 0; k < clause.fields.length; k++) {\n var field = clause.fields[k]\n requiredMatches[field] = requiredMatches[field].intersect(clauseMatches)\n }\n }\n }\n\n /**\n * Need to combine the field scoped required and prohibited\n * matching documents into a global set of required and prohibited\n * matches\n */\n var allRequiredMatches = lunr.Set.complete,\n allProhibitedMatches = lunr.Set.empty\n\n for (var i = 0; i < this.fields.length; i++) {\n var field = this.fields[i]\n\n if (requiredMatches[field]) {\n allRequiredMatches = allRequiredMatches.intersect(requiredMatches[field])\n }\n\n if (prohibitedMatches[field]) {\n allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field])\n }\n }\n\n var matchingFieldRefs = Object.keys(matchingFields),\n results = [],\n matches = Object.create(null)\n\n /*\n * If the query is negated (contains only prohibited terms)\n * we need to get _all_ fieldRefs currently existing in the\n * index. This is only done when we know that the query is\n * entirely prohibited terms to avoid any cost of getting all\n * fieldRefs unnecessarily.\n *\n * Additionally, blank MatchData must be created to correctly\n * populate the results.\n */\n if (query.isNegated()) {\n matchingFieldRefs = Object.keys(this.fieldVectors)\n\n for (var i = 0; i < matchingFieldRefs.length; i++) {\n var matchingFieldRef = matchingFieldRefs[i]\n var fieldRef = lunr.FieldRef.fromString(matchingFieldRef)\n matchingFields[matchingFieldRef] = new lunr.MatchData\n }\n }\n\n for (var i = 0; i < matchingFieldRefs.length; i++) {\n /*\n * Currently we have document fields that match the query, but we\n * need to return documents. The matchData and scores are combined\n * from multiple fields belonging to the same document.\n *\n * Scores are calculated by field, using the query vectors created\n * above, and combined into a final document score using addition.\n */\n var fieldRef = lunr.FieldRef.fromString(matchingFieldRefs[i]),\n docRef = fieldRef.docRef\n\n if (!allRequiredMatches.contains(docRef)) {\n continue\n }\n\n if (allProhibitedMatches.contains(docRef)) {\n continue\n }\n\n var fieldVector = this.fieldVectors[fieldRef],\n score = queryVectors[fieldRef.fieldName].similarity(fieldVector),\n docMatch\n\n if ((docMatch = matches[docRef]) !== undefined) {\n docMatch.score += score\n docMatch.matchData.combine(matchingFields[fieldRef])\n } else {\n var match = {\n ref: docRef,\n score: score,\n matchData: matchingFields[fieldRef]\n }\n matches[docRef] = match\n results.push(match)\n }\n }\n\n /*\n * Sort the results objects by score, highest first.\n */\n return results.sort(function (a, b) {\n return b.score - a.score\n })\n}\n\n/**\n * Prepares the index for JSON serialization.\n *\n * The schema for this JSON blob will be described in a\n * separate JSON schema file.\n *\n * @returns {Object}\n */\nlunr.Index.prototype.toJSON = function () {\n var invertedIndex = Object.keys(this.invertedIndex)\n .sort()\n .map(function (term) {\n return [term, this.invertedIndex[term]]\n }, this)\n\n var fieldVectors = Object.keys(this.fieldVectors)\n .map(function (ref) {\n return [ref, this.fieldVectors[ref].toJSON()]\n }, this)\n\n return {\n version: lunr.version,\n fields: this.fields,\n fieldVectors: fieldVectors,\n invertedIndex: invertedIndex,\n pipeline: this.pipeline.toJSON()\n }\n}\n\n/**\n * Loads a previously serialized lunr.Index\n *\n * @param {Object} serializedIndex - A previously serialized lunr.Index\n * @returns {lunr.Index}\n */\nlunr.Index.load = function (serializedIndex) {\n var attrs = {},\n fieldVectors = {},\n serializedVectors = serializedIndex.fieldVectors,\n invertedIndex = Object.create(null),\n serializedInvertedIndex = serializedIndex.invertedIndex,\n tokenSetBuilder = new lunr.TokenSet.Builder,\n pipeline = lunr.Pipeline.load(serializedIndex.pipeline)\n\n if (serializedIndex.version != lunr.version) {\n lunr.utils.warn(\"Version mismatch when loading serialised index. Current version of lunr '\" + lunr.version + \"' does not match serialized index '\" + serializedIndex.version + \"'\")\n }\n\n for (var i = 0; i < serializedVectors.length; i++) {\n var tuple = serializedVectors[i],\n ref = tuple[0],\n elements = tuple[1]\n\n fieldVectors[ref] = new lunr.Vector(elements)\n }\n\n for (var i = 0; i < serializedInvertedIndex.length; i++) {\n var tuple = serializedInvertedIndex[i],\n term = tuple[0],\n posting = tuple[1]\n\n tokenSetBuilder.insert(term)\n invertedIndex[term] = posting\n }\n\n tokenSetBuilder.finish()\n\n attrs.fields = serializedIndex.fields\n\n attrs.fieldVectors = fieldVectors\n attrs.invertedIndex = invertedIndex\n attrs.tokenSet = tokenSetBuilder.root\n attrs.pipeline = pipeline\n\n return new lunr.Index(attrs)\n}\n/*!\n * lunr.Builder\n * Copyright (C) 2020 Oliver Nightingale\n */\n\n/**\n * lunr.Builder performs indexing on a set of documents and\n * returns instances of lunr.Index ready for querying.\n *\n * All configuration of the index is done via the builder, the\n * fields to index, the document reference, the text processing\n * pipeline and document scoring parameters are all set on the\n * builder before indexing.\n *\n * @constructor\n * @property {string} _ref - Internal reference to the document reference field.\n * @property {string[]} _fields - Internal reference to the document fields to index.\n * @property {object} invertedIndex - The inverted index maps terms to document fields.\n * @property {object} documentTermFrequencies - Keeps track of document term frequencies.\n * @property {object} documentLengths - Keeps track of the length of documents added to the index.\n * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing.\n * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing.\n * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index.\n * @property {number} documentCount - Keeps track of the total number of documents indexed.\n * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75.\n * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2.\n * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space.\n * @property {array} metadataWhitelist - A list of metadata keys that have been whitelisted for entry in the index.\n */\nlunr.Builder = function () {\n this._ref = \"id\"\n this._fields = Object.create(null)\n this._documents = Object.create(null)\n this.invertedIndex = Object.create(null)\n this.fieldTermFrequencies = {}\n this.fieldLengths = {}\n this.tokenizer = lunr.tokenizer\n this.pipeline = new lunr.Pipeline\n this.searchPipeline = new lunr.Pipeline\n this.documentCount = 0\n this._b = 0.75\n this._k1 = 1.2\n this.termIndex = 0\n this.metadataWhitelist = []\n}\n\n/**\n * Sets the document field used as the document reference. Every document must have this field.\n * The type of this field in the document should be a string, if it is not a string it will be\n * coerced into a string by calling toString.\n *\n * The default ref is 'id'.\n *\n * The ref should _not_ be changed during indexing, it should be set before any documents are\n * added to the index. Changing it during indexing can lead to inconsistent results.\n *\n * @param {string} ref - The name of the reference field in the document.\n */\nlunr.Builder.prototype.ref = function (ref) {\n this._ref = ref\n}\n\n/**\n * A function that is used to extract a field from a document.\n *\n * Lunr expects a field to be at the top level of a document, if however the field\n * is deeply nested within a document an extractor function can be used to extract\n * the right field for indexing.\n *\n * @callback fieldExtractor\n * @param {object} doc - The document being added to the index.\n * @returns {?(string|object|object[])} obj - The object that will be indexed for this field.\n * @example Extracting a nested field\n * function (doc) { return doc.nested.field }\n */\n\n/**\n * Adds a field to the list of document fields that will be indexed. Every document being\n * indexed should have this field. Null values for this field in indexed documents will\n * not cause errors but will limit the chance of that document being retrieved by searches.\n *\n * All fields should be added before adding documents to the index. Adding fields after\n * a document has been indexed will have no effect on already indexed documents.\n *\n * Fields can be boosted at build time. This allows terms within that field to have more\n * importance when ranking search results. Use a field boost to specify that matches within\n * one field are more important than other fields.\n *\n * @param {string} fieldName - The name of a field to index in all documents.\n * @param {object} attributes - Optional attributes associated with this field.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this field.\n * @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document.\n * @throws {RangeError} fieldName cannot contain unsupported characters '/'\n */\nlunr.Builder.prototype.field = function (fieldName, attributes) {\n if (/\\//.test(fieldName)) {\n throw new RangeError (\"Field '\" + fieldName + \"' contains illegal character '/'\")\n }\n\n this._fields[fieldName] = attributes || {}\n}\n\n/**\n * A parameter to tune the amount of field length normalisation that is applied when\n * calculating relevance scores. A value of 0 will completely disable any normalisation\n * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b\n * will be clamped to the range 0 - 1.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.b = function (number) {\n if (number < 0) {\n this._b = 0\n } else if (number > 1) {\n this._b = 1\n } else {\n this._b = number\n }\n}\n\n/**\n * A parameter that controls the speed at which a rise in term frequency results in term\n * frequency saturation. The default value is 1.2. Setting this to a higher value will give\n * slower saturation levels, a lower value will result in quicker saturation.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.k1 = function (number) {\n this._k1 = number\n}\n\n/**\n * Adds a document to the index.\n *\n * Before adding fields to the index the index should have been fully setup, with the document\n * ref and all fields to index already having been specified.\n *\n * The document must have a field name as specified by the ref (by default this is 'id') and\n * it should have all fields defined for indexing, though null or undefined values will not\n * cause errors.\n *\n * Entire documents can be boosted at build time. Applying a boost to a document indicates that\n * this document should rank higher in search results than other documents.\n *\n * @param {object} doc - The document to add to the index.\n * @param {object} attributes - Optional attributes associated with this document.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this document.\n */\nlunr.Builder.prototype.add = function (doc, attributes) {\n var docRef = doc[this._ref],\n fields = Object.keys(this._fields)\n\n this._documents[docRef] = attributes || {}\n this.documentCount += 1\n\n for (var i = 0; i < fields.length; i++) {\n var fieldName = fields[i],\n extractor = this._fields[fieldName].extractor,\n field = extractor ? extractor(doc) : doc[fieldName],\n tokens = this.tokenizer(field, {\n fields: [fieldName]\n }),\n terms = this.pipeline.run(tokens),\n fieldRef = new lunr.FieldRef (docRef, fieldName),\n fieldTerms = Object.create(null)\n\n this.fieldTermFrequencies[fieldRef] = fieldTerms\n this.fieldLengths[fieldRef] = 0\n\n // store the length of this field for this document\n this.fieldLengths[fieldRef] += terms.length\n\n // calculate term frequencies for this field\n for (var j = 0; j < terms.length; j++) {\n var term = terms[j]\n\n if (fieldTerms[term] == undefined) {\n fieldTerms[term] = 0\n }\n\n fieldTerms[term] += 1\n\n // add to inverted index\n // create an initial posting if one doesn't exist\n if (this.invertedIndex[term] == undefined) {\n var posting = Object.create(null)\n posting[\"_index\"] = this.termIndex\n this.termIndex += 1\n\n for (var k = 0; k < fields.length; k++) {\n posting[fields[k]] = Object.create(null)\n }\n\n this.invertedIndex[term] = posting\n }\n\n // add an entry for this term/fieldName/docRef to the invertedIndex\n if (this.invertedIndex[term][fieldName][docRef] == undefined) {\n this.invertedIndex[term][fieldName][docRef] = Object.create(null)\n }\n\n // store all whitelisted metadata about this token in the\n // inverted index\n for (var l = 0; l < this.metadataWhitelist.length; l++) {\n var metadataKey = this.metadataWhitelist[l],\n metadata = term.metadata[metadataKey]\n\n if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) {\n this.invertedIndex[term][fieldName][docRef][metadataKey] = []\n }\n\n this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata)\n }\n }\n\n }\n}\n\n/**\n * Calculates the average document length for this index\n *\n * @private\n */\nlunr.Builder.prototype.calculateAverageFieldLengths = function () {\n\n var fieldRefs = Object.keys(this.fieldLengths),\n numberOfFields = fieldRefs.length,\n accumulator = {},\n documentsWithField = {}\n\n for (var i = 0; i < numberOfFields; i++) {\n var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n field = fieldRef.fieldName\n\n documentsWithField[field] || (documentsWithField[field] = 0)\n documentsWithField[field] += 1\n\n accumulator[field] || (accumulator[field] = 0)\n accumulator[field] += this.fieldLengths[fieldRef]\n }\n\n var fields = Object.keys(this._fields)\n\n for (var i = 0; i < fields.length; i++) {\n var fieldName = fields[i]\n accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName]\n }\n\n this.averageFieldLength = accumulator\n}\n\n/**\n * Builds a vector space model of every document using lunr.Vector\n *\n * @private\n */\nlunr.Builder.prototype.createFieldVectors = function () {\n var fieldVectors = {},\n fieldRefs = Object.keys(this.fieldTermFrequencies),\n fieldRefsLength = fieldRefs.length,\n termIdfCache = Object.create(null)\n\n for (var i = 0; i < fieldRefsLength; i++) {\n var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n fieldName = fieldRef.fieldName,\n fieldLength = this.fieldLengths[fieldRef],\n fieldVector = new lunr.Vector,\n termFrequencies = this.fieldTermFrequencies[fieldRef],\n terms = Object.keys(termFrequencies),\n termsLength = terms.length\n\n\n var fieldBoost = this._fields[fieldName].boost || 1,\n docBoost = this._documents[fieldRef.docRef].boost || 1\n\n for (var j = 0; j < termsLength; j++) {\n var term = terms[j],\n tf = termFrequencies[term],\n termIndex = this.invertedIndex[term]._index,\n idf, score, scoreWithPrecision\n\n if (termIdfCache[term] === undefined) {\n idf = lunr.idf(this.invertedIndex[term], this.documentCount)\n termIdfCache[term] = idf\n } else {\n idf = termIdfCache[term]\n }\n\n score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf)\n score *= fieldBoost\n score *= docBoost\n scoreWithPrecision = Math.round(score * 1000) / 1000\n // Converts 1.23456789 to 1.234.\n // Reducing the precision so that the vectors take up less\n // space when serialised. Doing it now so that they behave\n // the same before and after serialisation. Also, this is\n // the fastest approach to reducing a number's precision in\n // JavaScript.\n\n fieldVector.insert(termIndex, scoreWithPrecision)\n }\n\n fieldVectors[fieldRef] = fieldVector\n }\n\n this.fieldVectors = fieldVectors\n}\n\n/**\n * Creates a token set of all tokens in the index using lunr.TokenSet\n *\n * @private\n */\nlunr.Builder.prototype.createTokenSet = function () {\n this.tokenSet = lunr.TokenSet.fromArray(\n Object.keys(this.invertedIndex).sort()\n )\n}\n\n/**\n * Builds the index, creating an instance of lunr.Index.\n *\n * This completes the indexing process and should only be called\n * once all documents have been added to the index.\n *\n * @returns {lunr.Index}\n */\nlunr.Builder.prototype.build = function () {\n this.calculateAverageFieldLengths()\n this.createFieldVectors()\n this.createTokenSet()\n\n return new lunr.Index({\n invertedIndex: this.invertedIndex,\n fieldVectors: this.fieldVectors,\n tokenSet: this.tokenSet,\n fields: Object.keys(this._fields),\n pipeline: this.searchPipeline\n })\n}\n\n/**\n * Applies a plugin to the index builder.\n *\n * A plugin is a function that is called with the index builder as its context.\n * Plugins can be used to customise or extend the behaviour of the index\n * in some way. A plugin is just a function, that encapsulated the custom\n * behaviour that should be applied when building the index.\n *\n * The plugin function will be called with the index builder as its argument, additional\n * arguments can also be passed when calling use. The function will be called\n * with the index builder as its context.\n *\n * @param {Function} plugin The plugin to apply.\n */\nlunr.Builder.prototype.use = function (fn) {\n var args = Array.prototype.slice.call(arguments, 1)\n args.unshift(this)\n fn.apply(this, args)\n}\n/**\n * Contains and collects metadata about a matching document.\n * A single instance of lunr.MatchData is returned as part of every\n * lunr.Index~Result.\n *\n * @constructor\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n * @property {object} metadata - A cloned collection of metadata associated with this document.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData = function (term, field, metadata) {\n var clonedMetadata = Object.create(null),\n metadataKeys = Object.keys(metadata || {})\n\n // Cloning the metadata to prevent the original\n // being mutated during match data combination.\n // Metadata is kept in an array within the inverted\n // index so cloning the data can be done with\n // Array#slice\n for (var i = 0; i < metadataKeys.length; i++) {\n var key = metadataKeys[i]\n clonedMetadata[key] = metadata[key].slice()\n }\n\n this.metadata = Object.create(null)\n\n if (term !== undefined) {\n this.metadata[term] = Object.create(null)\n this.metadata[term][field] = clonedMetadata\n }\n}\n\n/**\n * An instance of lunr.MatchData will be created for every term that matches a\n * document. However only one instance is required in a lunr.Index~Result. This\n * method combines metadata from another instance of lunr.MatchData with this\n * objects metadata.\n *\n * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData.prototype.combine = function (otherMatchData) {\n var terms = Object.keys(otherMatchData.metadata)\n\n for (var i = 0; i < terms.length; i++) {\n var term = terms[i],\n fields = Object.keys(otherMatchData.metadata[term])\n\n if (this.metadata[term] == undefined) {\n this.metadata[term] = Object.create(null)\n }\n\n for (var j = 0; j < fields.length; j++) {\n var field = fields[j],\n keys = Object.keys(otherMatchData.metadata[term][field])\n\n if (this.metadata[term][field] == undefined) {\n this.metadata[term][field] = Object.create(null)\n }\n\n for (var k = 0; k < keys.length; k++) {\n var key = keys[k]\n\n if (this.metadata[term][field][key] == undefined) {\n this.metadata[term][field][key] = otherMatchData.metadata[term][field][key]\n } else {\n this.metadata[term][field][key] = this.metadata[term][field][key].concat(otherMatchData.metadata[term][field][key])\n }\n\n }\n }\n }\n}\n\n/**\n * Add metadata for a term/field pair to this instance of match data.\n *\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n */\nlunr.MatchData.prototype.add = function (term, field, metadata) {\n if (!(term in this.metadata)) {\n this.metadata[term] = Object.create(null)\n this.metadata[term][field] = metadata\n return\n }\n\n if (!(field in this.metadata[term])) {\n this.metadata[term][field] = metadata\n return\n }\n\n var metadataKeys = Object.keys(metadata)\n\n for (var i = 0; i < metadataKeys.length; i++) {\n var key = metadataKeys[i]\n\n if (key in this.metadata[term][field]) {\n this.metadata[term][field][key] = this.metadata[term][field][key].concat(metadata[key])\n } else {\n this.metadata[term][field][key] = metadata[key]\n }\n }\n}\n/**\n * A lunr.Query provides a programmatic way of defining queries to be performed\n * against a {@link lunr.Index}.\n *\n * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method\n * so the query object is pre-initialized with the right index fields.\n *\n * @constructor\n * @property {lunr.Query~Clause[]} clauses - An array of query clauses.\n * @property {string[]} allFields - An array of all available fields in a lunr.Index.\n */\nlunr.Query = function (allFields) {\n this.clauses = []\n this.allFields = allFields\n}\n\n/**\n * Constants for indicating what kind of automatic wildcard insertion will be used when constructing a query clause.\n *\n * This allows wildcards to be added to the beginning and end of a term without having to manually do any string\n * concatenation.\n *\n * The wildcard constants can be bitwise combined to select both leading and trailing wildcards.\n *\n * @constant\n * @default\n * @property {number} wildcard.NONE - The term will have no wildcards inserted, this is the default behaviour\n * @property {number} wildcard.LEADING - Prepend the term with a wildcard, unless a leading wildcard already exists\n * @property {number} wildcard.TRAILING - Append a wildcard to the term, unless a trailing wildcard already exists\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example query term with trailing wildcard\n * query.term('foo', { wildcard: lunr.Query.wildcard.TRAILING })\n * @example query term with leading and trailing wildcard\n * query.term('foo', {\n * wildcard: lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING\n * })\n */\n\nlunr.Query.wildcard = new String (\"*\")\nlunr.Query.wildcard.NONE = 0\nlunr.Query.wildcard.LEADING = 1\nlunr.Query.wildcard.TRAILING = 2\n\n/**\n * Constants for indicating what kind of presence a term must have in matching documents.\n *\n * @constant\n * @enum {number}\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example query term with required presence\n * query.term('foo', { presence: lunr.Query.presence.REQUIRED })\n */\nlunr.Query.presence = {\n /**\n * Term's presence in a document is optional, this is the default value.\n */\n OPTIONAL: 1,\n\n /**\n * Term's presence in a document is required, documents that do not contain\n * this term will not be returned.\n */\n REQUIRED: 2,\n\n /**\n * Term's presence in a document is prohibited, documents that do contain\n * this term will not be returned.\n */\n PROHIBITED: 3\n}\n\n/**\n * A single clause in a {@link lunr.Query} contains a term and details on how to\n * match that term against a {@link lunr.Index}.\n *\n * @typedef {Object} lunr.Query~Clause\n * @property {string[]} fields - The fields in an index this clause should be matched against.\n * @property {number} [boost=1] - Any boost that should be applied when matching this clause.\n * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be.\n * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline.\n * @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended.\n * @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents.\n */\n\n/**\n * Adds a {@link lunr.Query~Clause} to this query.\n *\n * Unless the clause contains the fields to be matched all fields will be matched. In addition\n * a default boost of 1 is applied to the clause.\n *\n * @param {lunr.Query~Clause} clause - The clause to add to this query.\n * @see lunr.Query~Clause\n * @returns {lunr.Query}\n */\nlunr.Query.prototype.clause = function (clause) {\n if (!('fields' in clause)) {\n clause.fields = this.allFields\n }\n\n if (!('boost' in clause)) {\n clause.boost = 1\n }\n\n if (!('usePipeline' in clause)) {\n clause.usePipeline = true\n }\n\n if (!('wildcard' in clause)) {\n clause.wildcard = lunr.Query.wildcard.NONE\n }\n\n if ((clause.wildcard & lunr.Query.wildcard.LEADING) && (clause.term.charAt(0) != lunr.Query.wildcard)) {\n clause.term = \"*\" + clause.term\n }\n\n if ((clause.wildcard & lunr.Query.wildcard.TRAILING) && (clause.term.slice(-1) != lunr.Query.wildcard)) {\n clause.term = \"\" + clause.term + \"*\"\n }\n\n if (!('presence' in clause)) {\n clause.presence = lunr.Query.presence.OPTIONAL\n }\n\n this.clauses.push(clause)\n\n return this\n}\n\n/**\n * A negated query is one in which every clause has a presence of\n * prohibited. These queries require some special processing to return\n * the expected results.\n *\n * @returns boolean\n */\nlunr.Query.prototype.isNegated = function () {\n for (var i = 0; i < this.clauses.length; i++) {\n if (this.clauses[i].presence != lunr.Query.presence.PROHIBITED) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause}\n * to the list of clauses that make up this query.\n *\n * The term is used as is, i.e. no tokenization will be performed by this method. Instead conversion\n * to a token or token-like string should be done before calling this method.\n *\n * The term will be converted to a string by calling `toString`. Multiple terms can be passed as an\n * array, each term in the array will share the same options.\n *\n * @param {object|object[]} term - The term(s) to add to the query.\n * @param {object} [options] - Any additional properties to add to the query clause.\n * @returns {lunr.Query}\n * @see lunr.Query#clause\n * @see lunr.Query~Clause\n * @example adding a single term to a query\n * query.term(\"foo\")\n * @example adding a single term to a query and specifying search fields, term boost and automatic trailing wildcard\n * query.term(\"foo\", {\n * fields: [\"title\"],\n * boost: 10,\n * wildcard: lunr.Query.wildcard.TRAILING\n * })\n * @example using lunr.tokenizer to convert a string to tokens before using them as terms\n * query.term(lunr.tokenizer(\"foo bar\"))\n */\nlunr.Query.prototype.term = function (term, options) {\n if (Array.isArray(term)) {\n term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this)\n return this\n }\n\n var clause = options || {}\n clause.term = term.toString()\n\n this.clause(clause)\n\n return this\n}\nlunr.QueryParseError = function (message, start, end) {\n this.name = \"QueryParseError\"\n this.message = message\n this.start = start\n this.end = end\n}\n\nlunr.QueryParseError.prototype = new Error\nlunr.QueryLexer = function (str) {\n this.lexemes = []\n this.str = str\n this.length = str.length\n this.pos = 0\n this.start = 0\n this.escapeCharPositions = []\n}\n\nlunr.QueryLexer.prototype.run = function () {\n var state = lunr.QueryLexer.lexText\n\n while (state) {\n state = state(this)\n }\n}\n\nlunr.QueryLexer.prototype.sliceString = function () {\n var subSlices = [],\n sliceStart = this.start,\n sliceEnd = this.pos\n\n for (var i = 0; i < this.escapeCharPositions.length; i++) {\n sliceEnd = this.escapeCharPositions[i]\n subSlices.push(this.str.slice(sliceStart, sliceEnd))\n sliceStart = sliceEnd + 1\n }\n\n subSlices.push(this.str.slice(sliceStart, this.pos))\n this.escapeCharPositions.length = 0\n\n return subSlices.join('')\n}\n\nlunr.QueryLexer.prototype.emit = function (type) {\n this.lexemes.push({\n type: type,\n str: this.sliceString(),\n start: this.start,\n end: this.pos\n })\n\n this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.escapeCharacter = function () {\n this.escapeCharPositions.push(this.pos - 1)\n this.pos += 1\n}\n\nlunr.QueryLexer.prototype.next = function () {\n if (this.pos >= this.length) {\n return lunr.QueryLexer.EOS\n }\n\n var char = this.str.charAt(this.pos)\n this.pos += 1\n return char\n}\n\nlunr.QueryLexer.prototype.width = function () {\n return this.pos - this.start\n}\n\nlunr.QueryLexer.prototype.ignore = function () {\n if (this.start == this.pos) {\n this.pos += 1\n }\n\n this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.backup = function () {\n this.pos -= 1\n}\n\nlunr.QueryLexer.prototype.acceptDigitRun = function () {\n var char, charCode\n\n do {\n char = this.next()\n charCode = char.charCodeAt(0)\n } while (charCode > 47 && charCode < 58)\n\n if (char != lunr.QueryLexer.EOS) {\n this.backup()\n }\n}\n\nlunr.QueryLexer.prototype.more = function () {\n return this.pos < this.length\n}\n\nlunr.QueryLexer.EOS = 'EOS'\nlunr.QueryLexer.FIELD = 'FIELD'\nlunr.QueryLexer.TERM = 'TERM'\nlunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE'\nlunr.QueryLexer.BOOST = 'BOOST'\nlunr.QueryLexer.PRESENCE = 'PRESENCE'\n\nlunr.QueryLexer.lexField = function (lexer) {\n lexer.backup()\n lexer.emit(lunr.QueryLexer.FIELD)\n lexer.ignore()\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexTerm = function (lexer) {\n if (lexer.width() > 1) {\n lexer.backup()\n lexer.emit(lunr.QueryLexer.TERM)\n }\n\n lexer.ignore()\n\n if (lexer.more()) {\n return lunr.QueryLexer.lexText\n }\n}\n\nlunr.QueryLexer.lexEditDistance = function (lexer) {\n lexer.ignore()\n lexer.acceptDigitRun()\n lexer.emit(lunr.QueryLexer.EDIT_DISTANCE)\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexBoost = function (lexer) {\n lexer.ignore()\n lexer.acceptDigitRun()\n lexer.emit(lunr.QueryLexer.BOOST)\n return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexEOS = function (lexer) {\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n}\n\n// This matches the separator used when tokenising fields\n// within a document. These should match otherwise it is\n// not possible to search for some tokens within a document.\n//\n// It is possible for the user to change the separator on the\n// tokenizer so it _might_ clash with any other of the special\n// characters already used within the search string, e.g. :.\n//\n// This means that it is possible to change the separator in\n// such a way that makes some words unsearchable using a search\n// string.\nlunr.QueryLexer.termSeparator = lunr.tokenizer.separator\n\nlunr.QueryLexer.lexText = function (lexer) {\n while (true) {\n var char = lexer.next()\n\n if (char == lunr.QueryLexer.EOS) {\n return lunr.QueryLexer.lexEOS\n }\n\n // Escape character is '\\'\n if (char.charCodeAt(0) == 92) {\n lexer.escapeCharacter()\n continue\n }\n\n if (char == \":\") {\n return lunr.QueryLexer.lexField\n }\n\n if (char == \"~\") {\n lexer.backup()\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n return lunr.QueryLexer.lexEditDistance\n }\n\n if (char == \"^\") {\n lexer.backup()\n if (lexer.width() > 0) {\n lexer.emit(lunr.QueryLexer.TERM)\n }\n return lunr.QueryLexer.lexBoost\n }\n\n // \"+\" indicates term presence is required\n // checking for length to ensure that only\n // leading \"+\" are considered\n if (char == \"+\" && lexer.width() === 1) {\n lexer.emit(lunr.QueryLexer.PRESENCE)\n return lunr.QueryLexer.lexText\n }\n\n // \"-\" indicates term presence is prohibited\n // checking for length to ensure that only\n // leading \"-\" are considered\n if (char == \"-\" && lexer.width() === 1) {\n lexer.emit(lunr.QueryLexer.PRESENCE)\n return lunr.QueryLexer.lexText\n }\n\n if (char.match(lunr.QueryLexer.termSeparator)) {\n return lunr.QueryLexer.lexTerm\n }\n }\n}\n\nlunr.QueryParser = function (str, query) {\n this.lexer = new lunr.QueryLexer (str)\n this.query = query\n this.currentClause = {}\n this.lexemeIdx = 0\n}\n\nlunr.QueryParser.prototype.parse = function () {\n this.lexer.run()\n this.lexemes = this.lexer.lexemes\n\n var state = lunr.QueryParser.parseClause\n\n while (state) {\n state = state(this)\n }\n\n return this.query\n}\n\nlunr.QueryParser.prototype.peekLexeme = function () {\n return this.lexemes[this.lexemeIdx]\n}\n\nlunr.QueryParser.prototype.consumeLexeme = function () {\n var lexeme = this.peekLexeme()\n this.lexemeIdx += 1\n return lexeme\n}\n\nlunr.QueryParser.prototype.nextClause = function () {\n var completedClause = this.currentClause\n this.query.clause(completedClause)\n this.currentClause = {}\n}\n\nlunr.QueryParser.parseClause = function (parser) {\n var lexeme = parser.peekLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n switch (lexeme.type) {\n case lunr.QueryLexer.PRESENCE:\n return lunr.QueryParser.parsePresence\n case lunr.QueryLexer.FIELD:\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expected either a field or a term, found \" + lexeme.type\n\n if (lexeme.str.length >= 1) {\n errorMessage += \" with value '\" + lexeme.str + \"'\"\n }\n\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n}\n\nlunr.QueryParser.parsePresence = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n switch (lexeme.str) {\n case \"-\":\n parser.currentClause.presence = lunr.Query.presence.PROHIBITED\n break\n case \"+\":\n parser.currentClause.presence = lunr.Query.presence.REQUIRED\n break\n default:\n var errorMessage = \"unrecognised presence operator'\" + lexeme.str + \"'\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n var errorMessage = \"expecting term or field, found nothing\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.FIELD:\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expecting term or field, found '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseField = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n if (parser.query.allFields.indexOf(lexeme.str) == -1) {\n var possibleFields = parser.query.allFields.map(function (f) { return \"'\" + f + \"'\" }).join(', '),\n errorMessage = \"unrecognised field '\" + lexeme.str + \"', possible fields: \" + possibleFields\n\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.fields = [lexeme.str]\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n var errorMessage = \"expecting term, found nothing\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n return lunr.QueryParser.parseTerm\n default:\n var errorMessage = \"expecting term, found '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseTerm = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n parser.currentClause.term = lexeme.str.toLowerCase()\n\n if (lexeme.str.indexOf(\"*\") != -1) {\n parser.currentClause.usePipeline = false\n }\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseEditDistance = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n var editDistance = parseInt(lexeme.str, 10)\n\n if (isNaN(editDistance)) {\n var errorMessage = \"edit distance must be numeric\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.editDistance = editDistance\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\nlunr.QueryParser.parseBoost = function (parser) {\n var lexeme = parser.consumeLexeme()\n\n if (lexeme == undefined) {\n return\n }\n\n var boost = parseInt(lexeme.str, 10)\n\n if (isNaN(boost)) {\n var errorMessage = \"boost must be numeric\"\n throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n }\n\n parser.currentClause.boost = boost\n\n var nextLexeme = parser.peekLexeme()\n\n if (nextLexeme == undefined) {\n parser.nextClause()\n return\n }\n\n switch (nextLexeme.type) {\n case lunr.QueryLexer.TERM:\n parser.nextClause()\n return lunr.QueryParser.parseTerm\n case lunr.QueryLexer.FIELD:\n parser.nextClause()\n return lunr.QueryParser.parseField\n case lunr.QueryLexer.EDIT_DISTANCE:\n return lunr.QueryParser.parseEditDistance\n case lunr.QueryLexer.BOOST:\n return lunr.QueryParser.parseBoost\n case lunr.QueryLexer.PRESENCE:\n parser.nextClause()\n return lunr.QueryParser.parsePresence\n default:\n var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n }\n}\n\n /**\n * export the module via AMD, CommonJS or as a browser global\n * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js\n */\n ;(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(factory)\n } else if (typeof exports === 'object') {\n /**\n * Node. Does not work with strict CommonJS, but\n * only CommonJS-like enviroments that support module.exports,\n * like Node.\n */\n module.exports = factory()\n } else {\n // Browser globals (root is window)\n root.lunr = factory()\n }\n }(this, function () {\n /**\n * Just return a value to define the module export.\n * This example returns an object, but the module\n * can return a function as the exported value.\n */\n return lunr\n }))\n})();\n", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport lunr from \"lunr\"\n\nimport \"~/polyfills\"\n\nimport { Search, SearchIndexConfig } from \"../../_\"\nimport {\n SearchMessage,\n SearchMessageType\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Add support for usage with `iframe-worker` polyfill\n *\n * While `importScripts` is synchronous when executed inside of a web worker,\n * it's not possible to provide a synchronous polyfilled implementation. The\n * cool thing is that awaiting a non-Promise is a noop, so extending the type\n * definition to return a `Promise` shouldn't break anything.\n *\n * @see https://bit.ly/2PjDnXi - GitHub comment\n */\ndeclare global {\n function importScripts(...urls: string[]): Promise | void\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index\n */\nlet index: Search\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch (= import) multi-language support through `lunr-languages`\n *\n * This function automatically imports the stemmers necessary to process the\n * languages, which are defined through the search index configuration.\n *\n * If the worker runs inside of an `iframe` (when using `iframe-worker` as\n * a shim), the base URL for the stemmers to be loaded must be determined by\n * searching for the first `script` element with a `src` attribute, which will\n * contain the contents of this script.\n *\n * @param config - Search index configuration\n *\n * @returns Promise resolving with no result\n */\nasync function setupSearchLanguages(\n config: SearchIndexConfig\n): Promise {\n let base = \"../lunr\"\n\n /* Detect `iframe-worker` and fix base URL */\n if (typeof parent !== \"undefined\" && \"IFrameWorker\" in parent) {\n const worker = document.querySelector(\"script[src]\")!\n const [path] = worker.src.split(\"/worker\")\n\n /* Prefix base with path */\n base = base.replace(\"..\", path)\n }\n\n /* Add scripts for languages */\n const scripts = []\n for (const lang of config.lang) {\n switch (lang) {\n\n /* Add segmenter for Japanese */\n case \"ja\":\n scripts.push(`${base}/tinyseg.js`)\n break\n\n /* Add segmenter for Hindi and Thai */\n case \"hi\":\n case \"th\":\n scripts.push(`${base}/wordcut.js`)\n break\n }\n\n /* Add language support */\n if (lang !== \"en\")\n scripts.push(`${base}/min/lunr.${lang}.min.js`)\n }\n\n /* Add multi-language support */\n if (config.lang.length > 1)\n scripts.push(`${base}/min/lunr.multi.min.js`)\n\n /* Load scripts synchronously */\n if (scripts.length)\n await importScripts(\n `${base}/min/lunr.stemmer.support.min.js`,\n ...scripts\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Message handler\n *\n * @param message - Source message\n *\n * @returns Target message\n */\nexport async function handler(\n message: SearchMessage\n): Promise {\n switch (message.type) {\n\n /* Search setup message */\n case SearchMessageType.SETUP:\n await setupSearchLanguages(message.data.config)\n index = new Search(message.data)\n return {\n type: SearchMessageType.READY\n }\n\n /* Search query message */\n case SearchMessageType.QUERY:\n return {\n type: SearchMessageType.RESULT,\n data: index ? index.search(message.data) : { items: [] }\n }\n\n /* All other messages */\n default:\n throw new TypeError(\"Invalid message type\")\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Worker\n * ------------------------------------------------------------------------- */\n\n/* @ts-expect-error - expose Lunr.js in global scope, or stemmers won't work */\nself.lunr = lunr\n\n/* Handle messages */\naddEventListener(\"message\", async ev => {\n postMessage(await handler(ev.data))\n})\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* Polyfill `Object.entries` */\nif (!Object.entries)\n Object.entries = function (obj: object) {\n const data: [string, string][] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push([key, obj[key]])\n\n /* Return entries */\n return data\n }\n\n/* Polyfill `Object.values` */\nif (!Object.values)\n Object.values = function (obj: object) {\n const data: string[] = []\n for (const key of Object.keys(obj))\n // @ts-expect-error - ignore property access warning\n data.push(obj[key])\n\n /* Return values */\n return data\n }\n\n/* ------------------------------------------------------------------------- */\n\n/* Polyfills for `Element` */\nif (typeof Element !== \"undefined\") {\n\n /* Polyfill `Element.scrollTo` */\n if (!Element.prototype.scrollTo)\n Element.prototype.scrollTo = function (\n x?: ScrollToOptions | number, y?: number\n ): void {\n if (typeof x === \"object\") {\n this.scrollLeft = x.left!\n this.scrollTop = x.top!\n } else {\n this.scrollLeft = x!\n this.scrollTop = y!\n }\n }\n\n /* Polyfill `Element.replaceWith` */\n if (!Element.prototype.replaceWith)\n Element.prototype.replaceWith = function (\n ...nodes: Array\n ): void {\n const parent = this.parentNode\n if (parent) {\n if (nodes.length === 0)\n parent.removeChild(this)\n\n /* Replace children and create text nodes */\n for (let i = nodes.length - 1; i >= 0; i--) {\n let node = nodes[i]\n if (typeof node === \"string\")\n node = document.createTextNode(node)\n else if (node.parentNode)\n node.parentNode.removeChild(node)\n\n /* Replace child or insert before previous sibling */\n if (!i)\n parent.replaceChild(node, this)\n else\n parent.insertBefore(this.previousSibling!, node)\n }\n }\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @returns Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map()\n const parents = new Set()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location, title and tags */\n const location = doc.location\n const title = doc.title\n const tags = doc.tags\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n ...tags && { tags }\n })\n }\n }\n return documents\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport escapeHTML from \"escape-html\"\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @returns Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @returns Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n * @param escape - Whether to escape HTML\n *\n * @returns Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig, escape: boolean\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}${term}`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => (\n escape\n ? escapeHTML(value)\n : value\n )\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)]*>/img, \"$1\")\n }\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query clause\n */\nexport interface SearchQueryClause {\n presence: lunr.Query.presence /* Clause presence */\n term: string /* Clause term */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search query terms\n */\nexport type SearchQueryTerms = Record\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Parse a search query for analysis\n *\n * @param value - Query value\n *\n * @returns Search query clauses\n */\nexport function parseSearchQuery(\n value: string\n): SearchQueryClause[] {\n const query = new (lunr as any).Query([\"title\", \"text\"])\n const parser = new (lunr as any).QueryParser(value, query)\n\n /* Parse and return query clauses */\n parser.parse()\n return query.clauses\n}\n\n/**\n * Analyze the search query clauses in regard to the search terms found\n *\n * @param query - Search query clauses\n * @param terms - Search terms\n *\n * @returns Search query terms\n */\nexport function getSearchQueryTerms(\n query: SearchQueryClause[], terms: string[]\n): SearchQueryTerms {\n const clauses = new Set(query)\n\n /* Match query clauses against terms */\n const result: SearchQueryTerms = {}\n for (let t = 0; t < terms.length; t++)\n for (const clause of clauses)\n if (terms[t].startsWith(clause.term)) {\n result[clause.term] = true\n clauses.delete(clause)\n }\n\n /* Annotate unmatched non-stopword query clauses */\n for (const clause of clauses)\n if (lunr.stopWordFilter?.(clause.term as any))\n result[clause.term] = false\n\n /* Return query terms */\n return result\n}\n", "/*\n * Copyright (c) 2016-2022 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n SearchDocument,\n SearchDocumentMap,\n setupSearchDocumentMap\n} from \"../document\"\nimport {\n SearchHighlightFactoryFn,\n setupSearchHighlighter\n} from \"../highlighter\"\nimport { SearchOptions } from \"../options\"\nimport {\n SearchQueryTerms,\n getSearchQueryTerms,\n parseSearchQuery\n} from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index configuration\n */\nexport interface SearchIndexConfig {\n lang: string[] /* Search languages */\n separator: string /* Search separator */\n}\n\n/**\n * Search index document\n */\nexport interface SearchIndexDocument {\n location: string /* Document location */\n title: string /* Document title */\n text: string /* Document text */\n tags?: string[] /* Document tags */\n boost?: number /* Document boost */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search index\n *\n * This interfaces describes the format of the `search_index.json` file which\n * is automatically built by the MkDocs search plugin.\n */\nexport interface SearchIndex {\n config: SearchIndexConfig /* Search index configuration */\n docs: SearchIndexDocument[] /* Search index documents */\n options: SearchOptions /* Search options */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search metadata\n */\nexport interface SearchMetadata {\n score: number /* Score (relevance) */\n terms: SearchQueryTerms /* Search query terms */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search result document\n */\nexport type SearchResultDocument = SearchDocument & SearchMetadata\n\n/**\n * Search result item\n */\nexport type SearchResultItem = SearchResultDocument[]\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search result\n */\nexport interface SearchResult {\n items: SearchResultItem[] /* Search result items */\n suggestions?: string[] /* Search suggestions */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute the difference of two lists of strings\n *\n * @param a - 1st list of strings\n * @param b - 2nd list of strings\n *\n * @returns Difference\n */\nfunction difference(a: string[], b: string[]): string[] {\n const [x, y] = [new Set(a), new Set(b)]\n return [\n ...new Set([...x].filter(value => !y.has(value)))\n ]\n}\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index\n */\nexport class Search {\n\n /**\n * Search document mapping\n *\n * A mapping of URLs (including hash fragments) to the actual articles and\n * sections of the documentation. The search document mapping must be created\n * regardless of whether the index was prebuilt or not, as Lunr.js itself\n * only stores the actual index.\n */\n protected documents: SearchDocumentMap\n\n /**\n * Search highlight factory function\n */\n protected highlight: SearchHighlightFactoryFn\n\n /**\n * The underlying Lunr.js search index\n */\n protected index: lunr.Index\n\n /**\n * Search options\n */\n protected options: SearchOptions\n\n /**\n * Create the search integration\n *\n * @param data - Search index\n */\n public constructor({ config, docs, options }: SearchIndex) {\n this.options = options\n\n /* Set up document map and highlighter factory */\n this.documents = setupSearchDocumentMap(docs)\n this.highlight = setupSearchHighlighter(config, false)\n\n /* Set separator for tokenizer */\n lunr.tokenizer.separator = new RegExp(config.separator)\n\n /* Create search index */\n this.index = lunr(function () {\n\n /* Set up multi-language support */\n if (config.lang.length === 1 && config.lang[0] !== \"en\") {\n this.use((lunr as any)[config.lang[0]])\n } else if (config.lang.length > 1) {\n this.use((lunr as any).multiLanguage(...config.lang))\n }\n\n /* Compute functions to be removed from the pipeline */\n const fns = difference([\n \"trimmer\", \"stopWordFilter\", \"stemmer\"\n ], options.pipeline)\n\n /* Remove functions from the pipeline for registered languages */\n for (const lang of config.lang.map(language => (\n language === \"en\" ? lunr : (lunr as any)[language]\n ))) {\n for (const fn of fns) {\n this.pipeline.remove(lang[fn])\n this.searchPipeline.remove(lang[fn])\n }\n }\n\n /* Set up reference */\n this.ref(\"location\")\n\n /* Set up fields */\n this.field(\"title\", { boost: 1e3 })\n this.field(\"text\")\n this.field(\"tags\", { boost: 1e6, extractor: doc => {\n const { tags = [] } = doc as SearchDocument\n return tags.reduce((list, tag) => [\n ...list,\n ...lunr.tokenizer(tag)\n ], [] as lunr.Token[])\n } })\n\n /* Index documents */\n for (const doc of docs)\n this.add(doc, { boost: doc.boost })\n })\n }\n\n /**\n * Search for matching documents\n *\n * The search index which MkDocs provides is divided up into articles, which\n * contain the whole content of the individual pages, and sections, which only\n * contain the contents of the subsections obtained by breaking the individual\n * pages up at `h1` ... `h6`. As there may be many sections on different pages\n * with identical titles (for example within this very project, e.g. \"Usage\"\n * or \"Installation\"), they need to be put into the context of the containing\n * page. For this reason, section results are grouped within their respective\n * articles which are the top-level results that are returned.\n *\n * @param query - Query value\n *\n * @returns Search results\n */\n public search(query: string): SearchResult {\n if (query) {\n try {\n const highlight = this.highlight(query)\n\n /* Parse query to extract clauses for analysis */\n const clauses = parseSearchQuery(query)\n .filter(clause => (\n clause.presence !== lunr.Query.presence.PROHIBITED\n ))\n\n /* Perform search and post-process results */\n const groups = this.index.search(`${query}*`)\n\n /* Apply post-query boosts based on title and search query terms */\n .reduce((item, { ref, score, matchData }) => {\n const document = this.documents.get(ref)\n if (typeof document !== \"undefined\") {\n const { location, title, text, tags, parent } = document\n\n /* Compute and analyze search query terms */\n const terms = getSearchQueryTerms(\n clauses,\n Object.keys(matchData.metadata)\n )\n\n /* Highlight title and text and apply post-query boosts */\n const boost = +!parent + +Object.values(terms).every(t => t)\n item.push({\n location,\n title: highlight(title),\n text: highlight(text),\n ...tags && { tags: tags.map(highlight) },\n score: score * (1 + boost),\n terms\n })\n }\n return item\n }, [])\n\n /* Sort search results again after applying boosts */\n .sort((a, b) => b.score - a.score)\n\n /* Group search results by page */\n .reduce((items, result) => {\n const document = this.documents.get(result.location)\n if (typeof document !== \"undefined\") {\n const ref = \"parent\" in document\n ? document.parent!.location\n : document.location\n items.set(ref, [...items.get(ref) || [], result])\n }\n return items\n }, new Map())\n\n /* Generate search suggestions, if desired */\n let suggestions: string[] | undefined\n if (this.options.suggestions) {\n const titles = this.index.query(builder => {\n for (const clause of clauses)\n builder.term(clause.term, {\n fields: [\"title\"],\n presence: lunr.Query.presence.REQUIRED,\n wildcard: lunr.Query.wildcard.TRAILING\n })\n })\n\n /* Retrieve suggestions for best match */\n suggestions = titles.length\n ? Object.keys(titles[0].matchData.metadata)\n : []\n }\n\n /* Return items and suggestions */\n return {\n items: [...groups.values()],\n ...typeof suggestions !== \"undefined\" && { suggestions }\n }\n\n /* Log errors to console (for now) */\n } catch {\n console.warn(`Invalid query: ${query} \u2013 see https://bit.ly/2s3ChXG`)\n }\n }\n\n /* Return nothing in case of error or empty query */\n return { items: [] }\n }\n}\n"], + "mappings": "glCAAA,IAAAA,GAAAC,EAAA,CAAAC,GAAAC,KAAA;AAAA;AAAA;AAAA;AAAA,IAME,UAAU,CAiCZ,IAAIC,EAAO,SAAUC,EAAQ,CAC3B,IAAIC,EAAU,IAAIF,EAAK,QAEvB,OAAAE,EAAQ,SAAS,IACfF,EAAK,QACLA,EAAK,eACLA,EAAK,OACP,EAEAE,EAAQ,eAAe,IACrBF,EAAK,OACP,EAEAC,EAAO,KAAKC,EAASA,CAAO,EACrBA,EAAQ,MAAM,CACvB,EAEAF,EAAK,QAAU,QACf;AAAA;AAAA;AAAA,GASAA,EAAK,MAAQ,CAAC,EASdA,EAAK,MAAM,KAAQ,SAAUG,EAAQ,CAEnC,OAAO,SAAUC,EAAS,CACpBD,EAAO,SAAW,QAAQ,MAC5B,QAAQ,KAAKC,CAAO,CAExB,CAEF,EAAG,IAAI,EAaPJ,EAAK,MAAM,SAAW,SAAUK,EAAK,CACnC,OAAsBA,GAAQ,KACrB,GAEAA,EAAI,SAAS,CAExB,EAkBAL,EAAK,MAAM,MAAQ,SAAUK,EAAK,CAChC,GAAIA,GAAQ,KACV,OAAOA,EAMT,QAHIC,EAAQ,OAAO,OAAO,IAAI,EAC1BC,EAAO,OAAO,KAAKF,CAAG,EAEjB,EAAI,EAAG,EAAIE,EAAK,OAAQ,IAAK,CACpC,IAAIC,EAAMD,EAAK,GACXE,EAAMJ,EAAIG,GAEd,GAAI,MAAM,QAAQC,CAAG,EAAG,CACtBH,EAAME,GAAOC,EAAI,MAAM,EACvB,QACF,CAEA,GAAI,OAAOA,GAAQ,UACf,OAAOA,GAAQ,UACf,OAAOA,GAAQ,UAAW,CAC5BH,EAAME,GAAOC,EACb,QACF,CAEA,MAAM,IAAI,UAAU,uDAAuD,CAC7E,CAEA,OAAOH,CACT,EACAN,EAAK,SAAW,SAAUU,EAAQC,EAAWC,EAAa,CACxD,KAAK,OAASF,EACd,KAAK,UAAYC,EACjB,KAAK,aAAeC,CACtB,EAEAZ,EAAK,SAAS,OAAS,IAEvBA,EAAK,SAAS,WAAa,SAAUa,EAAG,CACtC,IAAIC,EAAID,EAAE,QAAQb,EAAK,SAAS,MAAM,EAEtC,GAAIc,IAAM,GACR,KAAM,6BAGR,IAAIC,EAAWF,EAAE,MAAM,EAAGC,CAAC,EACvBJ,EAASG,EAAE,MAAMC,EAAI,CAAC,EAE1B,OAAO,IAAId,EAAK,SAAUU,EAAQK,EAAUF,CAAC,CAC/C,EAEAb,EAAK,SAAS,UAAU,SAAW,UAAY,CAC7C,OAAI,KAAK,cAAgB,OACvB,KAAK,aAAe,KAAK,UAAYA,EAAK,SAAS,OAAS,KAAK,QAG5D,KAAK,YACd,EACA;AAAA;AAAA;AAAA,GAUAA,EAAK,IAAM,SAAUgB,EAAU,CAG7B,GAFA,KAAK,SAAW,OAAO,OAAO,IAAI,EAE9BA,EAAU,CACZ,KAAK,OAASA,EAAS,OAEvB,QAASC,EAAI,EAAGA,EAAI,KAAK,OAAQA,IAC/B,KAAK,SAASD,EAASC,IAAM,EAEjC,MACE,KAAK,OAAS,CAElB,EASAjB,EAAK,IAAI,SAAW,CAClB,UAAW,SAAUkB,EAAO,CAC1B,OAAOA,CACT,EAEA,MAAO,UAAY,CACjB,OAAO,IACT,EAEA,SAAU,UAAY,CACpB,MAAO,EACT,CACF,EASAlB,EAAK,IAAI,MAAQ,CACf,UAAW,UAAY,CACrB,OAAO,IACT,EAEA,MAAO,SAAUkB,EAAO,CACtB,OAAOA,CACT,EAEA,SAAU,UAAY,CACpB,MAAO,EACT,CACF,EAQAlB,EAAK,IAAI,UAAU,SAAW,SAAUmB,EAAQ,CAC9C,MAAO,CAAC,CAAC,KAAK,SAASA,EACzB,EAUAnB,EAAK,IAAI,UAAU,UAAY,SAAUkB,EAAO,CAC9C,IAAIE,EAAGC,EAAGL,EAAUM,EAAe,CAAC,EAEpC,GAAIJ,IAAUlB,EAAK,IAAI,SACrB,OAAO,KAGT,GAAIkB,IAAUlB,EAAK,IAAI,MACrB,OAAOkB,EAGL,KAAK,OAASA,EAAM,QACtBE,EAAI,KACJC,EAAIH,IAEJE,EAAIF,EACJG,EAAI,MAGNL,EAAW,OAAO,KAAKI,EAAE,QAAQ,EAEjC,QAASH,EAAI,EAAGA,EAAID,EAAS,OAAQC,IAAK,CACxC,IAAIM,EAAUP,EAASC,GACnBM,KAAWF,EAAE,UACfC,EAAa,KAAKC,CAAO,CAE7B,CAEA,OAAO,IAAIvB,EAAK,IAAKsB,CAAY,CACnC,EASAtB,EAAK,IAAI,UAAU,MAAQ,SAAUkB,EAAO,CAC1C,OAAIA,IAAUlB,EAAK,IAAI,SACdA,EAAK,IAAI,SAGdkB,IAAUlB,EAAK,IAAI,MACd,KAGF,IAAIA,EAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,OAAO,OAAO,KAAKkB,EAAM,QAAQ,CAAC,CAAC,CACpF,EASAlB,EAAK,IAAM,SAAUwB,EAASC,EAAe,CAC3C,IAAIC,EAAoB,EAExB,QAASf,KAAaa,EAChBb,GAAa,WACjBe,GAAqB,OAAO,KAAKF,EAAQb,EAAU,EAAE,QAGvD,IAAIgB,GAAKF,EAAgBC,EAAoB,KAAQA,EAAoB,IAEzE,OAAO,KAAK,IAAI,EAAI,KAAK,IAAIC,CAAC,CAAC,CACjC,EAUA3B,EAAK,MAAQ,SAAU4B,EAAKC,EAAU,CACpC,KAAK,IAAMD,GAAO,GAClB,KAAK,SAAWC,GAAY,CAAC,CAC/B,EAOA7B,EAAK,MAAM,UAAU,SAAW,UAAY,CAC1C,OAAO,KAAK,GACd,EAsBAA,EAAK,MAAM,UAAU,OAAS,SAAU8B,EAAI,CAC1C,YAAK,IAAMA,EAAG,KAAK,IAAK,KAAK,QAAQ,EAC9B,IACT,EASA9B,EAAK,MAAM,UAAU,MAAQ,SAAU8B,EAAI,CACzC,OAAAA,EAAKA,GAAM,SAAUjB,EAAG,CAAE,OAAOA,CAAE,EAC5B,IAAIb,EAAK,MAAO8B,EAAG,KAAK,IAAK,KAAK,QAAQ,EAAG,KAAK,QAAQ,CACnE,EACA;AAAA;AAAA;AAAA,GAuBA9B,EAAK,UAAY,SAAUK,EAAKwB,EAAU,CACxC,GAAIxB,GAAO,MAAQA,GAAO,KACxB,MAAO,CAAC,EAGV,GAAI,MAAM,QAAQA,CAAG,EACnB,OAAOA,EAAI,IAAI,SAAU0B,EAAG,CAC1B,OAAO,IAAI/B,EAAK,MACdA,EAAK,MAAM,SAAS+B,CAAC,EAAE,YAAY,EACnC/B,EAAK,MAAM,MAAM6B,CAAQ,CAC3B,CACF,CAAC,EAOH,QAJID,EAAMvB,EAAI,SAAS,EAAE,YAAY,EACjC2B,EAAMJ,EAAI,OACVK,EAAS,CAAC,EAELC,EAAW,EAAGC,EAAa,EAAGD,GAAYF,EAAKE,IAAY,CAClE,IAAIE,EAAOR,EAAI,OAAOM,CAAQ,EAC1BG,EAAcH,EAAWC,EAE7B,GAAKC,EAAK,MAAMpC,EAAK,UAAU,SAAS,GAAKkC,GAAYF,EAAM,CAE7D,GAAIK,EAAc,EAAG,CACnB,IAAIC,EAAgBtC,EAAK,MAAM,MAAM6B,CAAQ,GAAK,CAAC,EACnDS,EAAc,SAAc,CAACH,EAAYE,CAAW,EACpDC,EAAc,MAAWL,EAAO,OAEhCA,EAAO,KACL,IAAIjC,EAAK,MACP4B,EAAI,MAAMO,EAAYD,CAAQ,EAC9BI,CACF,CACF,CACF,CAEAH,EAAaD,EAAW,CAC1B,CAEF,CAEA,OAAOD,CACT,EASAjC,EAAK,UAAU,UAAY,UAC3B;AAAA;AAAA;AAAA,GAkCAA,EAAK,SAAW,UAAY,CAC1B,KAAK,OAAS,CAAC,CACjB,EAEAA,EAAK,SAAS,oBAAsB,OAAO,OAAO,IAAI,EAmCtDA,EAAK,SAAS,iBAAmB,SAAU8B,EAAIS,EAAO,CAChDA,KAAS,KAAK,qBAChBvC,EAAK,MAAM,KAAK,6CAA+CuC,CAAK,EAGtET,EAAG,MAAQS,EACXvC,EAAK,SAAS,oBAAoB8B,EAAG,OAASA,CAChD,EAQA9B,EAAK,SAAS,4BAA8B,SAAU8B,EAAI,CACxD,IAAIU,EAAeV,EAAG,OAAUA,EAAG,SAAS,KAAK,oBAE5CU,GACHxC,EAAK,MAAM,KAAK;AAAA,EAAmG8B,CAAE,CAEzH,EAYA9B,EAAK,SAAS,KAAO,SAAUyC,EAAY,CACzC,IAAIC,EAAW,IAAI1C,EAAK,SAExB,OAAAyC,EAAW,QAAQ,SAAUE,EAAQ,CACnC,IAAIb,EAAK9B,EAAK,SAAS,oBAAoB2C,GAE3C,GAAIb,EACFY,EAAS,IAAIZ,CAAE,MAEf,OAAM,IAAI,MAAM,sCAAwCa,CAAM,CAElE,CAAC,EAEMD,CACT,EASA1C,EAAK,SAAS,UAAU,IAAM,UAAY,CACxC,IAAI4C,EAAM,MAAM,UAAU,MAAM,KAAK,SAAS,EAE9CA,EAAI,QAAQ,SAAUd,EAAI,CACxB9B,EAAK,SAAS,4BAA4B8B,CAAE,EAC5C,KAAK,OAAO,KAAKA,CAAE,CACrB,EAAG,IAAI,CACT,EAWA9B,EAAK,SAAS,UAAU,MAAQ,SAAU6C,EAAYC,EAAO,CAC3D9C,EAAK,SAAS,4BAA4B8C,CAAK,EAE/C,IAAIC,EAAM,KAAK,OAAO,QAAQF,CAAU,EACxC,GAAIE,GAAO,GACT,MAAM,IAAI,MAAM,wBAAwB,EAG1CA,EAAMA,EAAM,EACZ,KAAK,OAAO,OAAOA,EAAK,EAAGD,CAAK,CAClC,EAWA9C,EAAK,SAAS,UAAU,OAAS,SAAU6C,EAAYC,EAAO,CAC5D9C,EAAK,SAAS,4BAA4B8C,CAAK,EAE/C,IAAIC,EAAM,KAAK,OAAO,QAAQF,CAAU,EACxC,GAAIE,GAAO,GACT,MAAM,IAAI,MAAM,wBAAwB,EAG1C,KAAK,OAAO,OAAOA,EAAK,EAAGD,CAAK,CAClC,EAOA9C,EAAK,SAAS,UAAU,OAAS,SAAU8B,EAAI,CAC7C,IAAIiB,EAAM,KAAK,OAAO,QAAQjB,CAAE,EAC5BiB,GAAO,IAIX,KAAK,OAAO,OAAOA,EAAK,CAAC,CAC3B,EASA/C,EAAK,SAAS,UAAU,IAAM,SAAUiC,EAAQ,CAG9C,QAFIe,EAAc,KAAK,OAAO,OAErB/B,EAAI,EAAGA,EAAI+B,EAAa/B,IAAK,CAIpC,QAHIa,EAAK,KAAK,OAAOb,GACjBgC,EAAO,CAAC,EAEHC,EAAI,EAAGA,EAAIjB,EAAO,OAAQiB,IAAK,CACtC,IAAIC,EAASrB,EAAGG,EAAOiB,GAAIA,EAAGjB,CAAM,EAEpC,GAAI,EAAAkB,GAAW,MAA6BA,IAAW,IAEvD,GAAI,MAAM,QAAQA,CAAM,EACtB,QAASC,EAAI,EAAGA,EAAID,EAAO,OAAQC,IACjCH,EAAK,KAAKE,EAAOC,EAAE,OAGrBH,EAAK,KAAKE,CAAM,CAEpB,CAEAlB,EAASgB,CACX,CAEA,OAAOhB,CACT,EAYAjC,EAAK,SAAS,UAAU,UAAY,SAAU4B,EAAKC,EAAU,CAC3D,IAAIwB,EAAQ,IAAIrD,EAAK,MAAO4B,EAAKC,CAAQ,EAEzC,OAAO,KAAK,IAAI,CAACwB,CAAK,CAAC,EAAE,IAAI,SAAUtB,EAAG,CACxC,OAAOA,EAAE,SAAS,CACpB,CAAC,CACH,EAMA/B,EAAK,SAAS,UAAU,MAAQ,UAAY,CAC1C,KAAK,OAAS,CAAC,CACjB,EASAA,EAAK,SAAS,UAAU,OAAS,UAAY,CAC3C,OAAO,KAAK,OAAO,IAAI,SAAU8B,EAAI,CACnC,OAAA9B,EAAK,SAAS,4BAA4B8B,CAAE,EAErCA,EAAG,KACZ,CAAC,CACH,EACA;AAAA;AAAA;AAAA,GAqBA9B,EAAK,OAAS,SAAUgB,EAAU,CAChC,KAAK,WAAa,EAClB,KAAK,SAAWA,GAAY,CAAC,CAC/B,EAaAhB,EAAK,OAAO,UAAU,iBAAmB,SAAUsD,EAAO,CAExD,GAAI,KAAK,SAAS,QAAU,EAC1B,MAAO,GAST,QANIC,EAAQ,EACRC,EAAM,KAAK,SAAS,OAAS,EAC7BnB,EAAcmB,EAAMD,EACpBE,EAAa,KAAK,MAAMpB,EAAc,CAAC,EACvCqB,EAAa,KAAK,SAASD,EAAa,GAErCpB,EAAc,IACfqB,EAAaJ,IACfC,EAAQE,GAGNC,EAAaJ,IACfE,EAAMC,GAGJC,GAAcJ,IAIlBjB,EAAcmB,EAAMD,EACpBE,EAAaF,EAAQ,KAAK,MAAMlB,EAAc,CAAC,EAC/CqB,EAAa,KAAK,SAASD,EAAa,GAO1C,GAJIC,GAAcJ,GAIdI,EAAaJ,EACf,OAAOG,EAAa,EAGtB,GAAIC,EAAaJ,EACf,OAAQG,EAAa,GAAK,CAE9B,EAWAzD,EAAK,OAAO,UAAU,OAAS,SAAU2D,EAAWlD,EAAK,CACvD,KAAK,OAAOkD,EAAWlD,EAAK,UAAY,CACtC,KAAM,iBACR,CAAC,CACH,EAUAT,EAAK,OAAO,UAAU,OAAS,SAAU2D,EAAWlD,EAAKqB,EAAI,CAC3D,KAAK,WAAa,EAClB,IAAI8B,EAAW,KAAK,iBAAiBD,CAAS,EAE1C,KAAK,SAASC,IAAaD,EAC7B,KAAK,SAASC,EAAW,GAAK9B,EAAG,KAAK,SAAS8B,EAAW,GAAInD,CAAG,EAEjE,KAAK,SAAS,OAAOmD,EAAU,EAAGD,EAAWlD,CAAG,CAEpD,EAOAT,EAAK,OAAO,UAAU,UAAY,UAAY,CAC5C,GAAI,KAAK,WAAY,OAAO,KAAK,WAKjC,QAHI6D,EAAe,EACfC,EAAiB,KAAK,SAAS,OAE1B7C,EAAI,EAAGA,EAAI6C,EAAgB7C,GAAK,EAAG,CAC1C,IAAIR,EAAM,KAAK,SAASQ,GACxB4C,GAAgBpD,EAAMA,CACxB,CAEA,OAAO,KAAK,WAAa,KAAK,KAAKoD,CAAY,CACjD,EAQA7D,EAAK,OAAO,UAAU,IAAM,SAAU+D,EAAa,CAOjD,QANIC,EAAa,EACb5C,EAAI,KAAK,SAAUC,EAAI0C,EAAY,SACnCE,EAAO7C,EAAE,OAAQ8C,EAAO7C,EAAE,OAC1B8C,EAAO,EAAGC,EAAO,EACjBnD,EAAI,EAAGiC,EAAI,EAERjC,EAAIgD,GAAQf,EAAIgB,GACrBC,EAAO/C,EAAEH,GAAImD,EAAO/C,EAAE6B,GAClBiB,EAAOC,EACTnD,GAAK,EACIkD,EAAOC,EAChBlB,GAAK,EACIiB,GAAQC,IACjBJ,GAAc5C,EAAEH,EAAI,GAAKI,EAAE6B,EAAI,GAC/BjC,GAAK,EACLiC,GAAK,GAIT,OAAOc,CACT,EASAhE,EAAK,OAAO,UAAU,WAAa,SAAU+D,EAAa,CACxD,OAAO,KAAK,IAAIA,CAAW,EAAI,KAAK,UAAU,GAAK,CACrD,EAOA/D,EAAK,OAAO,UAAU,QAAU,UAAY,CAG1C,QAFIqE,EAAS,IAAI,MAAO,KAAK,SAAS,OAAS,CAAC,EAEvCpD,EAAI,EAAGiC,EAAI,EAAGjC,EAAI,KAAK,SAAS,OAAQA,GAAK,EAAGiC,IACvDmB,EAAOnB,GAAK,KAAK,SAASjC,GAG5B,OAAOoD,CACT,EAOArE,EAAK,OAAO,UAAU,OAAS,UAAY,CACzC,OAAO,KAAK,QACd,EAEA;AAAA;AAAA;AAAA;AAAA,GAiBAA,EAAK,QAAW,UAAU,CACxB,IAAIsE,EAAY,CACZ,QAAY,MACZ,OAAW,OACX,KAAS,OACT,KAAS,OACT,KAAS,MACT,IAAQ,MACR,KAAS,KACT,MAAU,MACV,IAAQ,IACR,MAAU,MACV,QAAY,MACZ,MAAU,MACV,KAAS,MACT,MAAU,KACV,QAAY,MACZ,QAAY,MACZ,QAAY,MACZ,MAAU,KACV,MAAU,MACV,OAAW,MACX,KAAS,KACX,EAEAC,EAAY,CACV,MAAU,KACV,MAAU,GACV,MAAU,KACV,MAAU,KACV,KAAS,KACT,IAAQ,GACR,KAAS,EACX,EAEAC,EAAI,WACJC,EAAI,WACJC,EAAIF,EAAI,aACRG,EAAIF,EAAI,WAERG,EAAO,KAAOF,EAAI,KAAOC,EAAID,EAC7BG,EAAO,KAAOH,EAAI,KAAOC,EAAID,EAAI,IAAMC,EAAI,MAC3CG,EAAO,KAAOJ,EAAI,KAAOC,EAAID,EAAIC,EAAID,EACrCK,EAAM,KAAOL,EAAI,KAAOD,EAEtBO,EAAU,IAAI,OAAOJ,CAAI,EACzBK,EAAU,IAAI,OAAOH,CAAI,EACzBI,EAAU,IAAI,OAAOL,CAAI,EACzBM,EAAS,IAAI,OAAOJ,CAAG,EAEvBK,EAAQ,kBACRC,EAAS,iBACTC,EAAQ,aACRC,EAAS,kBACTC,EAAU,KACVC,EAAW,cACXC,EAAW,IAAI,OAAO,oBAAoB,EAC1CC,EAAW,IAAI,OAAO,IAAMjB,EAAID,EAAI,cAAc,EAElDmB,EAAQ,mBACRC,EAAO,2IAEPC,EAAO,iDAEPC,EAAO,sFACPC,EAAQ,oBAERC,EAAO,WACPC,EAAS,MACTC,EAAQ,IAAI,OAAO,IAAMzB,EAAID,EAAI,cAAc,EAE/C2B,EAAgB,SAAuBC,EAAG,CAC5C,IAAIC,EACFC,EACAC,EACAC,EACAC,EACAC,EACAC,EAEF,GAAIP,EAAE,OAAS,EAAK,OAAOA,EAiB3B,GAfAG,EAAUH,EAAE,OAAO,EAAE,CAAC,EAClBG,GAAW,MACbH,EAAIG,EAAQ,YAAY,EAAIH,EAAE,OAAO,CAAC,GAIxCI,EAAKrB,EACLsB,EAAMrB,EAEFoB,EAAG,KAAKJ,CAAC,EAAKA,EAAIA,EAAE,QAAQI,EAAG,MAAM,EAChCC,EAAI,KAAKL,CAAC,IAAKA,EAAIA,EAAE,QAAQK,EAAI,MAAM,GAGhDD,EAAKnB,EACLoB,EAAMnB,EACFkB,EAAG,KAAKJ,CAAC,EAAG,CACd,IAAIQ,EAAKJ,EAAG,KAAKJ,CAAC,EAClBI,EAAKzB,EACDyB,EAAG,KAAKI,EAAG,EAAE,IACfJ,EAAKjB,EACLa,EAAIA,EAAE,QAAQI,EAAG,EAAE,EAEvB,SAAWC,EAAI,KAAKL,CAAC,EAAG,CACtB,IAAIQ,EAAKH,EAAI,KAAKL,CAAC,EACnBC,EAAOO,EAAG,GACVH,EAAMvB,EACFuB,EAAI,KAAKJ,CAAI,IACfD,EAAIC,EACJI,EAAMjB,EACNkB,EAAMjB,EACNkB,EAAMjB,EACFe,EAAI,KAAKL,CAAC,EAAKA,EAAIA,EAAI,IAClBM,EAAI,KAAKN,CAAC,GAAKI,EAAKjB,EAASa,EAAIA,EAAE,QAAQI,EAAG,EAAE,GAChDG,EAAI,KAAKP,CAAC,IAAKA,EAAIA,EAAI,KAEpC,CAIA,GADAI,EAAKb,EACDa,EAAG,KAAKJ,CAAC,EAAG,CACd,IAAIQ,EAAKJ,EAAG,KAAKJ,CAAC,EAClBC,EAAOO,EAAG,GACVR,EAAIC,EAAO,GACb,CAIA,GADAG,EAAKZ,EACDY,EAAG,KAAKJ,CAAC,EAAG,CACd,IAAIQ,EAAKJ,EAAG,KAAKJ,CAAC,EAClBC,EAAOO,EAAG,GACVN,EAASM,EAAG,GACZJ,EAAKzB,EACDyB,EAAG,KAAKH,CAAI,IACdD,EAAIC,EAAOhC,EAAUiC,GAEzB,CAIA,GADAE,EAAKX,EACDW,EAAG,KAAKJ,CAAC,EAAG,CACd,IAAIQ,EAAKJ,EAAG,KAAKJ,CAAC,EAClBC,EAAOO,EAAG,GACVN,EAASM,EAAG,GACZJ,EAAKzB,EACDyB,EAAG,KAAKH,CAAI,IACdD,EAAIC,EAAO/B,EAAUgC,GAEzB,CAKA,GAFAE,EAAKV,EACLW,EAAMV,EACFS,EAAG,KAAKJ,CAAC,EAAG,CACd,IAAIQ,EAAKJ,EAAG,KAAKJ,CAAC,EAClBC,EAAOO,EAAG,GACVJ,EAAKxB,EACDwB,EAAG,KAAKH,CAAI,IACdD,EAAIC,EAER,SAAWI,EAAI,KAAKL,CAAC,EAAG,CACtB,IAAIQ,EAAKH,EAAI,KAAKL,CAAC,EACnBC,EAAOO,EAAG,GAAKA,EAAG,GAClBH,EAAMzB,EACFyB,EAAI,KAAKJ,CAAI,IACfD,EAAIC,EAER,CAIA,GADAG,EAAKR,EACDQ,EAAG,KAAKJ,CAAC,EAAG,CACd,IAAIQ,EAAKJ,EAAG,KAAKJ,CAAC,EAClBC,EAAOO,EAAG,GACVJ,EAAKxB,EACLyB,EAAMxB,EACNyB,EAAMR,GACFM,EAAG,KAAKH,CAAI,GAAMI,EAAI,KAAKJ,CAAI,GAAK,CAAEK,EAAI,KAAKL,CAAI,KACrDD,EAAIC,EAER,CAEA,OAAAG,EAAKP,EACLQ,EAAMzB,EACFwB,EAAG,KAAKJ,CAAC,GAAKK,EAAI,KAAKL,CAAC,IAC1BI,EAAKjB,EACLa,EAAIA,EAAE,QAAQI,EAAG,EAAE,GAKjBD,GAAW,MACbH,EAAIG,EAAQ,YAAY,EAAIH,EAAE,OAAO,CAAC,GAGjCA,CACT,EAEA,OAAO,SAAUhD,EAAO,CACtB,OAAOA,EAAM,OAAO+C,CAAa,CACnC,CACF,EAAG,EAEHpG,EAAK,SAAS,iBAAiBA,EAAK,QAAS,SAAS,EACtD;AAAA;AAAA;AAAA,GAkBAA,EAAK,uBAAyB,SAAU8G,EAAW,CACjD,IAAIC,EAAQD,EAAU,OAAO,SAAU7D,EAAM+D,EAAU,CACrD,OAAA/D,EAAK+D,GAAYA,EACV/D,CACT,EAAG,CAAC,CAAC,EAEL,OAAO,SAAUI,EAAO,CACtB,GAAIA,GAAS0D,EAAM1D,EAAM,SAAS,KAAOA,EAAM,SAAS,EAAG,OAAOA,CACpE,CACF,EAeArD,EAAK,eAAiBA,EAAK,uBAAuB,CAChD,IACA,OACA,QACA,SACA,QACA,MACA,SACA,OACA,KACA,QACA,KACA,MACA,MACA,MACA,KACA,KACA,KACA,UACA,OACA,MACA,KACA,MACA,SACA,QACA,OACA,MACA,KACA,OACA,SACA,OACA,OACA,QACA,MACA,OACA,MACA,MACA,MACA,MACA,OACA,KACA,MACA,OACA,MACA,MACA,MACA,UACA,IACA,KACA,KACA,OACA,KACA,KACA,MACA,OACA,QACA,MACA,OACA,SACA,MACA,KACA,QACA,OACA,OACA,KACA,UACA,KACA,MACA,MACA,KACA,MACA,QACA,KACA,OACA,KACA,QACA,MACA,MACA,SACA,OACA,MACA,OACA,MACA,SACA,QACA,KACA,OACA,OACA,OACA,MACA,QACA,OACA,OACA,QACA,QACA,OACA,OACA,MACA,KACA,MACA,OACA,KACA,QACA,MACA,KACA,OACA,OACA,OACA,QACA,QACA,QACA,MACA,OACA,MACA,OACA,OACA,QACA,MACA,MACA,MACF,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", + "names": ["require_lunr", "__commonJSMin", "exports", "module", "lunr", "config", "builder", "global", "message", "obj", "clone", "keys", "key", "val", "docRef", "fieldName", "stringValue", "s", "n", "fieldRef", "elements", "i", "other", "object", "a", "b", "intersection", "element", "posting", "documentCount", "documentsWithTerm", "x", "str", "metadata", "fn", "t", "len", "tokens", "sliceEnd", "sliceStart", "char", "sliceLength", "tokenMetadata", "label", "isRegistered", "serialised", "pipeline", "fnName", "fns", "existingFn", "newFn", "pos", "stackLength", "memo", "j", "result", "k", "token", "index", "start", "end", "pivotPoint", "pivotIndex", "insertIdx", "position", "sumOfSquares", "elementsLength", "otherVector", "dotProduct", "aLen", "bLen", "aVal", "bVal", "output", "step2list", "step3list", "c", "v", "C", "V", "mgr0", "meq1", "mgr1", "s_v", "re_mgr0", "re_mgr1", "re_meq1", "re_s_v", "re_1a", "re2_1a", "re_1b", "re2_1b", "re_1b_2", "re2_1b_2", "re3_1b_2", "re4_1b_2", "re_1c", "re_2", "re_3", "re_4", "re2_4", "re_5", "re_5_1", "re3_5", "porterStemmer", "w", "stem", "suffix", "firstch", "re", "re2", "re3", "re4", "fp", "stopWords", "words", "stopWord", "arr", "clause", "editDistance", "root", "stack", "frame", "noEditNode", "insertionNode", "substitutionNode", "charA", "charB", "transposeNode", "node", "final", "next", "edges", "edge", "labels", "qEdges", "qLen", "nEdges", "nLen", "q", "qEdge", "nEdge", "qNode", "word", "commonPrefix", "nextNode", "downTo", "childKey", "attrs", "queryString", "query", "parser", "matchingFields", "queryVectors", "termFieldCache", "requiredMatches", "prohibitedMatches", "terms", "clauseMatches", "m", "term", "termTokenSet", "expandedTerms", "field", "expandedTerm", "termIndex", "fieldPosting", "matchingDocumentRefs", "termField", "matchingDocumentsSet", "l", "matchingDocumentRef", "matchingFieldRef", "fieldMatch", "allRequiredMatches", "allProhibitedMatches", "matchingFieldRefs", "results", "matches", "fieldVector", "score", "docMatch", "match", "invertedIndex", "fieldVectors", "ref", "serializedIndex", "serializedVectors", "serializedInvertedIndex", "tokenSetBuilder", "tuple", "attributes", "number", "doc", "fields", "extractor", "fieldTerms", "metadataKey", "fieldRefs", "numberOfFields", "accumulator", "documentsWithField", "fieldRefsLength", "termIdfCache", "fieldLength", "termFrequencies", "termsLength", "fieldBoost", "docBoost", "tf", "idf", "scoreWithPrecision", "args", "clonedMetadata", "metadataKeys", "otherMatchData", "allFields", "options", "state", "subSlices", "type", "charCode", "lexer", "lexeme", "completedClause", "errorMessage", "nextLexeme", "possibleFields", "f", "boost", "factory", "require_escape_html", "__commonJSMin", "exports", "module", "matchHtmlRegExp", "escapeHtml", "string", "str", "match", "escape", "html", "index", "lastIndex", "import_lunr", "obj", "data", "key", "x", "y", "nodes", "parent", "i", "node", "import_escape_html", "setupSearchDocumentMap", "docs", "documents", "parents", "doc", "path", "hash", "location", "title", "tags", "text", "escapeHTML", "parent", "__spreadValues", "import_escape_html", "setupSearchHighlighter", "config", "escape", "separator", "highlight", "_", "data", "term", "query", "match", "value", "escapeHTML", "parseSearchQuery", "value", "query", "getSearchQueryTerms", "terms", "_a", "clauses", "result", "t", "clause", "difference", "a", "b", "x", "y", "value", "Search", "config", "docs", "options", "setupSearchDocumentMap", "setupSearchHighlighter", "fns", "lang", "language", "fn", "doc", "tags", "list", "tag", "query", "highlight", "clauses", "parseSearchQuery", "clause", "groups", "item", "ref", "score", "matchData", "document", "location", "title", "text", "parent", "terms", "getSearchQueryTerms", "boost", "t", "__spreadProps", "__spreadValues", "items", "result", "suggestions", "titles", "builder", "e", "index", "setupSearchLanguages", "config", "__async", "base", "worker", "path", "scripts", "lang", "handler", "message", "Search", "lunr", "ev"] +} diff --git a/assets/stylesheets/extra.0d2c79a8.min.css b/assets/stylesheets/extra.0d2c79a8.min.css new file mode 100644 index 000000000..6e23ef17d --- /dev/null +++ b/assets/stylesheets/extra.0d2c79a8.min.css @@ -0,0 +1 @@ +@charset "UTF-8";@keyframes ᴴₒᴴₒᴴₒ{0%{transform:translate3d(var(--left-start),0,0)}to{transform:translate3d(var(--left-end),110vh,0)}}.ᴴₒᴴₒᴴₒ{--size:1vw;background:#fff;border:1px solid #ddd;border-radius:50%;cursor:pointer;height:var(--size);opacity:1;position:fixed;top:-5vh;transition:opacity 1s;width:var(--size);z-index:10}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):first-child{--size:0.4vw;--left-start:7vw;--left-end:-8vw;animation:ᴴₒᴴₒᴴₒ 12s linear infinite both;animation-delay:-4s;left:24vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(2){--size:0.4vw;--left-start:9vw;--left-end:0vw;animation:ᴴₒᴴₒᴴₒ 18s linear infinite both;animation-delay:-2s;left:68vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(3){--size:0.4vw;--left-start:1vw;--left-end:7vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-6s;left:10vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(4){--size:0.5vw;--left-start:8vw;--left-end:10vw;animation:ᴴₒᴴₒᴴₒ 18s linear infinite both;animation-delay:-8s;left:63vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(5){--size:0.5vw;--left-start:5vw;--left-end:9vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-4s;left:58vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(6){--size:0.1vw;--left-start:3vw;--left-end:10vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-1s;left:55vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(7){--size:0.2vw;--left-start:-2vw;--left-end:6vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-7s;left:50vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(8){--size:0.3vw;--left-start:7vw;--left-end:7vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-3s;left:65vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(9){--size:0.2vw;--left-start:4vw;--left-end:5vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-2s;left:1vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(10){--size:0.3vw;--left-start:2vw;--left-end:-3vw;animation:ᴴₒᴴₒᴴₒ 12s linear infinite both;animation-delay:-10s;left:92vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(11){--size:0.2vw;--left-start:1vw;--left-end:8vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-6s;left:5vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(12){--size:0.4vw;--left-start:9vw;--left-end:1vw;animation:ᴴₒᴴₒᴴₒ 18s linear infinite both;animation-delay:-3s;left:77vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(13){--size:0.1vw;--left-start:-3vw;--left-end:3vw;animation:ᴴₒᴴₒᴴₒ 18s linear infinite both;animation-delay:-7s;left:93vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(14){--size:0.5vw;--left-start:0vw;--left-end:-5vw;animation:ᴴₒᴴₒᴴₒ 12s linear infinite both;animation-delay:-4s;left:35vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(15){--size:0.1vw;--left-start:-9vw;--left-end:4vw;animation:ᴴₒᴴₒᴴₒ 20s linear infinite both;animation-delay:-6s;left:15vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(16){--size:0.1vw;--left-start:1vw;--left-end:9vw;animation:ᴴₒᴴₒᴴₒ 17s linear infinite both;animation-delay:-6s;left:100vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(17){--size:0.1vw;--left-start:1vw;--left-end:0vw;animation:ᴴₒᴴₒᴴₒ 17s linear infinite both;animation-delay:-1s;left:44vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(18){--size:0.4vw;--left-start:-9vw;--left-end:-9vw;animation:ᴴₒᴴₒᴴₒ 16s linear infinite both;animation-delay:-6s;left:69vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(19){--size:0.2vw;--left-start:3vw;--left-end:-8vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-1s;left:32vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(20){--size:0.1vw;--left-start:-7vw;--left-end:8vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-8s;left:59vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(21){--size:0.2vw;--left-start:-1vw;--left-end:-8vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-6s;left:96vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(22){--size:0.2vw;--left-start:9vw;--left-end:1vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-7s;left:78vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(23){--size:0.4vw;--left-start:5vw;--left-end:-2vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-10s;left:29vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(24){--size:0.1vw;--left-start:-4vw;--left-end:1vw;animation:ᴴₒᴴₒᴴₒ 20s linear infinite both;animation-delay:-7s;left:83vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(25){--size:0.3vw;--left-start:-1vw;--left-end:2vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-8s;left:95vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(26){--size:0.5vw;--left-start:-3vw;--left-end:-6vw;animation:ᴴₒᴴₒᴴₒ 18s linear infinite both;animation-delay:-8s;left:74vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(27){--size:0.5vw;--left-start:9vw;--left-end:-9vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-2s;left:94vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(28){--size:0.1vw;--left-start:0vw;--left-end:-4vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-4s;left:95vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(29){--size:0.5vw;--left-start:8vw;--left-end:4vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-3s;left:42vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(30){--size:0.4vw;--left-start:-5vw;--left-end:0vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-10s;left:8vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(31){--size:0.4vw;--left-start:-7vw;--left-end:3vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-4s;left:77vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(32){--size:0.4vw;--left-start:8vw;--left-end:-5vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-3s;left:80vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(33){--size:0.2vw;--left-start:-3vw;--left-end:8vw;animation:ᴴₒᴴₒᴴₒ 20s linear infinite both;animation-delay:-6s;left:15vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(34){--size:0.5vw;--left-start:5vw;--left-end:1vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-1s;left:91vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(35){--size:0.3vw;--left-start:-6vw;--left-end:-5vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-5s;left:93vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(36){--size:0.1vw;--left-start:10vw;--left-end:10vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-10s;left:59vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(37){--size:0.3vw;--left-start:4vw;--left-end:6vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-8s;left:35vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(38){--size:0.5vw;--left-start:8vw;--left-end:-3vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-6s;left:6vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(39){--size:0.2vw;--left-start:-6vw;--left-end:-2vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-7s;left:58vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(40){--size:0.4vw;--left-start:3vw;--left-end:-5vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-4s;left:15vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(41){--size:0.1vw;--left-start:2vw;--left-end:-7vw;animation:ᴴₒᴴₒᴴₒ 17s linear infinite both;animation-delay:-7s;left:24vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(42){--size:0.3vw;--left-start:8vw;--left-end:3vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-9s;left:36vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(43){--size:0.2vw;--left-start:-9vw;--left-end:-3vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-10s;left:23vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(44){--size:0.1vw;--left-start:4vw;--left-end:-6vw;animation:ᴴₒᴴₒᴴₒ 16s linear infinite both;animation-delay:-6s;left:9vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(45){--size:0.1vw;--left-start:-3vw;--left-end:-5vw;animation:ᴴₒᴴₒᴴₒ 19s linear infinite both;animation-delay:-5s;left:62vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(46){--size:0.3vw;--left-start:0vw;--left-end:2vw;animation:ᴴₒᴴₒᴴₒ 20s linear infinite both;animation-delay:-4s;left:1vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(47){--size:0.4vw;--left-start:8vw;--left-end:-4vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-1s;left:76vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(48){--size:0.2vw;--left-start:5vw;--left-end:-3vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-5s;left:19vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(49){--size:0.4vw;--left-start:1vw;--left-end:-1vw;animation:ᴴₒᴴₒᴴₒ 18s linear infinite both;animation-delay:-4s;left:72vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(50){--size:0.4vw;--left-start:8vw;--left-end:-6vw;animation:ᴴₒᴴₒᴴₒ 16s linear infinite both;animation-delay:-10s;left:25vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(51){--size:0.1vw;--left-start:-5vw;--left-end:-8vw;animation:ᴴₒᴴₒᴴₒ 17s linear infinite both;animation-delay:-9s;left:71vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(52){--size:0.4vw;--left-start:-4vw;--left-end:9vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-7s;left:30vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(53){--size:0.5vw;--left-start:-1vw;--left-end:-8vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-4s;left:37vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(54){--size:0.4vw;--left-start:-1vw;--left-end:-1vw;animation:ᴴₒᴴₒᴴₒ 12s linear infinite both;animation-delay:-9s;left:48vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(55){--size:0.5vw;--left-start:8vw;--left-end:6vw;animation:ᴴₒᴴₒᴴₒ 20s linear infinite both;animation-delay:-6s;left:65vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(56){--size:0.4vw;--left-start:9vw;--left-end:5vw;animation:ᴴₒᴴₒᴴₒ 18s linear infinite both;animation-delay:-6s;left:53vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(57){--size:0.4vw;--left-start:3vw;--left-end:-9vw;animation:ᴴₒᴴₒᴴₒ 12s linear infinite both;animation-delay:-1s;left:76vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(58){--size:0.2vw;--left-start:-7vw;--left-end:0vw;animation:ᴴₒᴴₒᴴₒ 16s linear infinite both;animation-delay:-9s;left:54vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(59){--size:0.1vw;--left-start:-9vw;--left-end:-2vw;animation:ᴴₒᴴₒᴴₒ 20s linear infinite both;animation-delay:-1s;left:66vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(60){--size:0.3vw;--left-start:-6vw;--left-end:2vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-7s;left:91vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(61){--size:0.4vw;--left-start:6vw;--left-end:-8vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-7s;left:35vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(62){--size:0.4vw;--left-start:-6vw;--left-end:2vw;animation:ᴴₒᴴₒᴴₒ 16s linear infinite both;animation-delay:-3s;left:86vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(63){--size:0.5vw;--left-start:-7vw;--left-end:7vw;animation:ᴴₒᴴₒᴴₒ 20s linear infinite both;animation-delay:-5s;left:86vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(64){--size:0.2vw;--left-start:-9vw;--left-end:1vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-5s;left:53vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(65){--size:0.2vw;--left-start:-2vw;--left-end:3vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-6s;left:56vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(66){--size:0.5vw;--left-start:1vw;--left-end:8vw;animation:ᴴₒᴴₒᴴₒ 17s linear infinite both;animation-delay:-5s;left:58vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(67){--size:0.5vw;--left-start:2vw;--left-end:9vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-5s;left:14vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(68){--size:0.3vw;--left-start:-1vw;--left-end:6vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-1s;left:100vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(69){--size:0.2vw;--left-start:9vw;--left-end:-2vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-7s;left:8vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(70){--size:0.4vw;--left-start:-5vw;--left-end:8vw;animation:ᴴₒᴴₒᴴₒ 11s linear infinite both;animation-delay:-4s;left:82vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(71){--size:0.4vw;--left-start:3vw;--left-end:-7vw;animation:ᴴₒᴴₒᴴₒ 13s linear infinite both;animation-delay:-6s;left:26vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(72){--size:0.2vw;--left-start:-2vw;--left-end:-3vw;animation:ᴴₒᴴₒᴴₒ 15s linear infinite both;animation-delay:-3s;left:24vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(73){--size:0.3vw;--left-start:-7vw;--left-end:-8vw;animation:ᴴₒᴴₒᴴₒ 16s linear infinite both;animation-delay:-2s;left:2vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(74){--size:0.4vw;--left-start:-9vw;--left-end:-3vw;animation:ᴴₒᴴₒᴴₒ 14s linear infinite both;animation-delay:-10s;left:94vw}.ᴴₒᴴₒᴴₒ:not(.ᴴₒᴴₒᴴₒ--gotcha):nth-child(75){--size:0.3vw;--left-start:7vw;--left-end:2vw;animation:ᴴₒᴴₒᴴₒ 17s linear infinite both;animation-delay:-2s;left:26vw}.ᴴₒᴴₒᴴₒ:nth-child(5n){filter:blur(2px)}.ᴴₒᴴₒᴴₒ--ᵍₒᵗ꜀ᴴₐ{opacity:0}.ᴴₒᴴₒᴴₒ__button{display:block}.ᴴₒᴴₒᴴₒ__button:after{background-color:currentcolor;content:"";display:block;height:24px;margin:0 auto;-webkit-mask-image:url('data:image/svg+xml;charset=utf-8,');mask-image:url('data:image/svg+xml;charset=utf-8,');-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:24px}.ᴴₒᴴₒᴴₒ__button[hidden]:after{-webkit-mask-image:url('data:image/svg+xml;charset=utf-8,');mask-image:url('data:image/svg+xml;charset=utf-8,')} \ No newline at end of file diff --git a/assets/stylesheets/extra.0d2c79a8.min.css.map b/assets/stylesheets/extra.0d2c79a8.min.css.map new file mode 100644 index 000000000..cd262c03a --- /dev/null +++ b/assets/stylesheets/extra.0d2c79a8.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/assets/stylesheets/extra.scss","../../../src/assets/stylesheets/extra.scss"],"names":[],"mappings":"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","file":"extra.css"} \ No newline at end of file diff --git a/assets/stylesheets/main.975780f9.min.css b/assets/stylesheets/main.975780f9.min.css new file mode 100644 index 000000000..dac48ba77 --- /dev/null +++ b/assets/stylesheets/main.975780f9.min.css @@ -0,0 +1 @@ +@charset "UTF-8";html{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none;box-sizing:border-box}*,:after,:before{box-sizing:inherit}@media (prefers-reduced-motion){*,:after,:before{transition:none!important}}body{margin:0}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}hr{border:0;box-sizing:initial;display:block;height:.05rem;overflow:visible;padding:0}small{font-size:80%}sub,sup{line-height:1em}img{border-style:none}table{border-collapse:initial;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{background:#0000;border:0;font-family:inherit;font-size:inherit;margin:0;padding:0}input{border:0;outline:none}:root{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}:root,[data-md-color-scheme=default]{--md-default-fg-color:#000000de;--md-default-fg-color--light:#0000008a;--md-default-fg-color--lighter:#00000052;--md-default-fg-color--lightest:#00000012;--md-default-bg-color:#fff;--md-default-bg-color--light:#ffffffb3;--md-default-bg-color--lighter:#ffffff4d;--md-default-bg-color--lightest:#ffffff1f;--md-code-fg-color:#36464e;--md-code-bg-color:#f5f5f5;--md-code-hl-color:#ffff0080;--md-code-hl-number-color:#d52a2a;--md-code-hl-special-color:#db1457;--md-code-hl-function-color:#a846b9;--md-code-hl-constant-color:#6e59d9;--md-code-hl-keyword-color:#3f6ec6;--md-code-hl-string-color:#1c7d4d;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:#ffff0080;--md-typeset-del-color:#f5503d26;--md-typeset-ins-color:#0bd57026;--md-typeset-kbd-color:#fafafa;--md-typeset-kbd-accent-color:#fff;--md-typeset-kbd-border-color:#b8b8b8;--md-typeset-table-color:#0000001f;--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-fg-color:#fff;--md-footer-fg-color--light:#ffffffb3;--md-footer-fg-color--lighter:#ffffff4d;--md-footer-bg-color:#000000de;--md-footer-bg-color--dark:#00000052;--md-shadow-z1:0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000001a,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0003,0 0 0.05rem #00000059}.md-icon svg{fill:currentcolor;display:block;height:1.2rem;width:1.2rem}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--md-text-font-family:var(--md-text-font,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;--md-code-font-family:var(--md-code-font,_),SFMono-Regular,Consolas,Menlo,monospace}body,input{font-feature-settings:"kern","liga";font-family:var(--md-text-font-family)}body,code,input,kbd,pre{color:var(--md-typeset-color)}code,kbd,pre{font-feature-settings:"kern";font-family:var(--md-code-font-family)}:root{--md-typeset-table-sort-icon:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--asc:url('data:image/svg+xml;charset=utf-8,');--md-typeset-table-sort-icon--desc:url('data:image/svg+xml;charset=utf-8,')}.md-typeset{-webkit-print-color-adjust:exact;color-adjust:exact;font-size:.8rem;line-height:1.6}@media print{.md-typeset{font-size:.68rem}}.md-typeset blockquote,.md-typeset dl,.md-typeset figure,.md-typeset ol,.md-typeset pre,.md-typeset ul{margin-bottom:1em;margin-top:1em}.md-typeset h1{color:var(--md-default-fg-color--light);font-size:2em;line-height:1.3;margin:0 0 1.25em}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{font-size:1.5625em;line-height:1.4;margin:1.6em 0 .64em}.md-typeset h3{font-size:1.25em;font-weight:400;letter-spacing:-.01em;line-height:1.5;margin:1.6em 0 .8em}.md-typeset h2+h3{margin-top:.8em}.md-typeset h4{font-weight:700;letter-spacing:-.01em;margin:1em 0}.md-typeset h5,.md-typeset h6{color:var(--md-default-fg-color--light);font-size:.8em;font-weight:700;letter-spacing:-.01em;margin:1.25em 0}.md-typeset h5{text-transform:uppercase}.md-typeset hr{border-bottom:.05rem solid var(--md-default-fg-color--lightest);display:flow-root;margin:1.5em 0}.md-typeset a{color:var(--md-typeset-a-color);word-break:break-word}.md-typeset a,.md-typeset a:before{transition:color 125ms}.md-typeset a:focus,.md-typeset a:hover{color:var(--md-accent-fg-color)}.md-typeset a:focus code,.md-typeset a:hover code{background-color:var(--md-accent-fg-color--transparent)}.md-typeset a code{color:currentcolor;transition:background-color 125ms}.md-typeset a.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset code,.md-typeset kbd,.md-typeset pre{color:var(--md-code-fg-color);direction:ltr;font-variant-ligatures:none}@media print{.md-typeset code,.md-typeset kbd,.md-typeset pre{white-space:pre-wrap}}.md-typeset code{background-color:var(--md-code-bg-color);border-radius:.1rem;-webkit-box-decoration-break:clone;box-decoration-break:clone;font-size:.85em;padding:0 .2941176471em;word-break:break-word}.md-typeset code:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-typeset pre{display:flow-root;line-height:1.4;position:relative}.md-typeset pre>code{-webkit-box-decoration-break:slice;box-decoration-break:slice;box-shadow:none;display:block;margin:0;outline-color:var(--md-accent-fg-color);overflow:auto;padding:.7720588235em 1.1764705882em;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin;touch-action:auto;word-break:normal}.md-typeset pre>code:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-typeset pre>code::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset pre>code::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset pre>code::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset kbd{background-color:var(--md-typeset-kbd-color);border-radius:.1rem;box-shadow:0 .1rem 0 .05rem var(--md-typeset-kbd-border-color),0 .1rem 0 var(--md-typeset-kbd-border-color),0 -.1rem .2rem var(--md-typeset-kbd-accent-color) inset;color:var(--md-default-fg-color);display:inline-block;font-size:.75em;padding:0 .6666666667em;vertical-align:text-top;word-break:break-word}.md-typeset mark{background-color:var(--md-typeset-mark-color);-webkit-box-decoration-break:clone;box-decoration-break:clone;color:inherit;word-break:break-word}.md-typeset abbr{border-bottom:.05rem dotted var(--md-default-fg-color--light);cursor:help;text-decoration:none}@media (hover:none){.md-typeset abbr{position:relative}.md-typeset abbr[title]:-webkit-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}.md-typeset abbr[title]:-moz-any(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}[dir=ltr] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{left:0}[dir=ltr] .md-typeset abbr[title]:is(:focus,:hover):after{left:0}[dir=rtl] .md-typeset abbr[title]:-webkit-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:-moz-any(:focus,:hover):after{right:0}[dir=rtl] .md-typeset abbr[title]:is(:focus,:hover):after{right:0}.md-typeset abbr[title]:is(:focus,:hover):after{background-color:var(--md-default-fg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z3);color:var(--md-default-bg-color);content:attr(title);display:inline-block;font-size:.7rem;margin-top:2em;max-width:80%;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;padding:.2rem .3rem;position:absolute;width:auto}}.md-typeset small{opacity:.75}[dir=ltr] .md-typeset sub,[dir=ltr] .md-typeset sup{margin-left:.078125em}[dir=rtl] .md-typeset sub,[dir=rtl] .md-typeset sup{margin-right:.078125em}[dir=ltr] .md-typeset blockquote{padding-left:.6rem}[dir=rtl] .md-typeset blockquote{padding-right:.6rem}[dir=ltr] .md-typeset blockquote{border-left:.2rem solid var(--md-default-fg-color--lighter)}[dir=rtl] .md-typeset blockquote{border-right:.2rem solid var(--md-default-fg-color--lighter)}.md-typeset blockquote{color:var(--md-default-fg-color--light);margin-left:0;margin-right:0}.md-typeset ul{list-style-type:disc}[dir=ltr] .md-typeset ol,[dir=ltr] .md-typeset ul{margin-left:.625em}[dir=rtl] .md-typeset ol,[dir=rtl] .md-typeset ul{margin-right:.625em}.md-typeset ol,.md-typeset ul{padding:0}.md-typeset ol:not([hidden]),.md-typeset ul:not([hidden]){display:flow-root}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}[dir=ltr] .md-typeset ol li,[dir=ltr] .md-typeset ul li{margin-left:1.25em}[dir=rtl] .md-typeset ol li,[dir=rtl] .md-typeset ul li{margin-right:1.25em}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}.md-typeset ol li :-webkit-any(ul,ol),.md-typeset ul li :-webkit-any(ul,ol){margin-bottom:.5em;margin-top:.5em}.md-typeset ol li :-moz-any(ul,ol),.md-typeset ul li :-moz-any(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset ol li :-webkit-any(ul,ol),[dir=ltr] .md-typeset ul li :-webkit-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :-moz-any(ul,ol),[dir=ltr] .md-typeset ul li :-moz-any(ul,ol){margin-left:.625em}[dir=ltr] .md-typeset ol li :is(ul,ol),[dir=ltr] .md-typeset ul li :is(ul,ol){margin-left:.625em}[dir=rtl] .md-typeset ol li :-webkit-any(ul,ol),[dir=rtl] .md-typeset ul li :-webkit-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :-moz-any(ul,ol),[dir=rtl] .md-typeset ul li :-moz-any(ul,ol){margin-right:.625em}[dir=rtl] .md-typeset ol li :is(ul,ol),[dir=rtl] .md-typeset ul li :is(ul,ol){margin-right:.625em}.md-typeset ol li :is(ul,ol),.md-typeset ul li :is(ul,ol){margin-bottom:.5em;margin-top:.5em}[dir=ltr] .md-typeset dd{margin-left:1.875em}[dir=rtl] .md-typeset dd{margin-right:1.875em}.md-typeset dd{margin-bottom:1.5em;margin-top:1em}.md-typeset img,.md-typeset svg,.md-typeset video{height:auto;max-width:100%}.md-typeset img[align=left]{margin:1em 1em 1em 0}.md-typeset img[align=right]{margin:1em 0 1em 1em}.md-typeset img[align]:only-child{margin-top:0}.md-typeset img[src$="#gh-dark-mode-only"],.md-typeset img[src$="#only-dark"]{display:none}.md-typeset figure{display:flow-root;margin:1em auto;max-width:100%;text-align:center;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.md-typeset figure img{display:block}.md-typeset figcaption{font-style:italic;margin:1em auto;max-width:24rem}.md-typeset iframe{max-width:100%}.md-typeset table:not([class]){background-color:var(--md-default-bg-color);border:.05rem solid var(--md-typeset-table-color);border-radius:.1rem;display:inline-block;font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto}@media print{.md-typeset table:not([class]){display:table}}.md-typeset table:not([class])+*{margin-top:1.5em}.md-typeset table:not([class]) :-webkit-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-moz-any(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :is(th,td)>:first-child{margin-top:0}.md-typeset table:not([class]) :-webkit-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-moz-any(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :is(th,td)>:last-child{margin-bottom:0}.md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:left}.md-typeset table:not([class]) :is(th,td):not([align]){text-align:left}[dir=rtl] .md-typeset table:not([class]) :-webkit-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :-moz-any(th,td):not([align]){text-align:right}[dir=rtl] .md-typeset table:not([class]) :is(th,td):not([align]){text-align:right}.md-typeset table:not([class]) th{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) td{border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.md-typeset table:not([class]) tbody tr{transition:background-color 125ms}.md-typeset table:not([class]) tbody tr:hover{background-color:rgba(0,0,0,.035);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset}.md-typeset table:not([class]) a{word-break:normal}.md-typeset table th[role=columnheader]{cursor:pointer}[dir=ltr] .md-typeset table th[role=columnheader]:after{margin-left:.5em}[dir=rtl] .md-typeset table th[role=columnheader]:after{margin-right:.5em}.md-typeset table th[role=columnheader]:after{content:"";display:inline-block;height:1.2em;-webkit-mask-image:var(--md-typeset-table-sort-icon);mask-image:var(--md-typeset-table-sort-icon);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset table th[role=columnheader]:hover:after{background-color:var(--md-default-fg-color--lighter)}.md-typeset table th[role=columnheader][aria-sort=ascending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--asc);mask-image:var(--md-typeset-table-sort-icon--asc)}.md-typeset table th[role=columnheader][aria-sort=descending]:after{background-color:var(--md-default-fg-color--light);-webkit-mask-image:var(--md-typeset-table-sort-icon--desc);mask-image:var(--md-typeset-table-sort-icon--desc)}.md-typeset__scrollwrap{margin:1em -.8rem;overflow-x:auto;touch-action:auto}.md-typeset__table{display:inline-block;margin-bottom:.5em;padding:0 .8rem}@media print{.md-typeset__table{display:block}}html .md-typeset__table table{display:table;margin:0;overflow:hidden;width:100%}@media screen and (max-width:44.9375em){.md-content__inner>pre{margin:1em -.8rem}.md-content__inner>pre code{border-radius:0}}.md-banner{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color);overflow:auto}@media print{.md-banner{display:none}}.md-banner--warning{background:var(--md-typeset-mark-color);color:var(--md-default-fg-color)}.md-banner__inner{font-size:.7rem;margin:.6rem auto;padding:0 .8rem}[dir=ltr] .md-banner__button{float:right}[dir=rtl] .md-banner__button{float:left}.md-banner__button{color:inherit;cursor:pointer;transition:opacity .25s}.md-banner__button:hover{opacity:.7}html{font-size:125%;height:100%;overflow-x:hidden}@media screen and (min-width:100em){html{font-size:137.5%}}@media screen and (min-width:125em){html{font-size:150%}}body{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;font-size:.5rem;min-height:100%;position:relative;width:100%}@media print{body{display:block}}@media screen and (max-width:59.9375em){body[data-md-scrolllock]{position:fixed}}.md-grid{margin-left:auto;margin-right:auto;max-width:61rem}.md-container{display:flex;flex-direction:column;flex-grow:1}@media print{.md-container{display:block}}.md-main{flex-grow:1}.md-main__inner{display:flex;height:100%;margin-top:1.5rem}.md-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.md-toggle{display:none}.md-option{height:0;opacity:0;position:absolute;width:0}.md-option:checked+label:not([hidden]){display:block}.md-option.focus-visible+label{outline-color:var(--md-accent-fg-color);outline-style:auto}.md-skip{background-color:var(--md-default-fg-color);border-radius:.1rem;color:var(--md-default-bg-color);font-size:.64rem;margin:.5rem;opacity:0;outline-color:var(--md-accent-fg-color);padding:.3rem .5rem;position:fixed;transform:translateY(.4rem);z-index:-1}.md-skip:focus{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 175ms 75ms;z-index:10}@page{margin:25mm}:root{--md-clipboard-icon:url('data:image/svg+xml;charset=utf-8,')}.md-clipboard{border-radius:.1rem;color:var(--md-default-fg-color--lightest);cursor:pointer;height:1.5em;outline-color:var(--md-accent-fg-color);outline-offset:.1rem;position:absolute;right:.5em;top:.5em;transition:color .25s;width:1.5em;z-index:1}@media print{.md-clipboard{display:none}}.md-clipboard:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}:hover>.md-clipboard{color:var(--md-default-fg-color--light)}.md-clipboard:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-clipboard:after{background-color:currentcolor;content:"";display:block;height:1.125em;margin:0 auto;-webkit-mask-image:var(--md-clipboard-icon);mask-image:var(--md-clipboard-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:1.125em}.md-clipboard--inline{cursor:pointer}.md-clipboard--inline code{transition:color .25s,background-color .25s}.md-clipboard--inline:-webkit-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:-moz-any(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-clipboard--inline:is(:focus,:hover) code{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}@keyframes consent{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes overlay{0%{opacity:0}to{opacity:1}}.md-consent__overlay{animation:overlay .25s both;-webkit-backdrop-filter:blur(.1rem);backdrop-filter:blur(.1rem);background-color:#0000008a;height:100%;opacity:1;position:fixed;top:0;width:100%;z-index:5}.md-consent__inner{animation:consent .5s cubic-bezier(.1,.7,.1,1) both;background-color:var(--md-default-bg-color);border:0;border-radius:.1rem;bottom:0;box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;max-height:100%;overflow:auto;padding:0;position:fixed;width:100%;z-index:5}.md-consent__form{padding:.8rem}.md-consent__settings{display:none;margin:1em 0}input:checked+.md-consent__settings{display:block}.md-consent__controls{margin-bottom:.8rem}.md-typeset .md-consent__controls .md-button{display:inline}@media screen and (max-width:44.9375em){.md-typeset .md-consent__controls .md-button{display:block;margin-top:.4rem;text-align:center;width:100%}}.md-consent label{cursor:pointer}.md-content{flex-grow:1;min-width:0}.md-content__inner{margin:0 .8rem 1.2rem;padding-top:.6rem}@media screen and (min-width:76.25em){[dir=ltr] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}[dir=ltr] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner,[dir=rtl] .md-sidebar--primary:not([hidden])~.md-content>.md-content__inner{margin-right:1.2rem}[dir=rtl] .md-sidebar--secondary:not([hidden])~.md-content>.md-content__inner{margin-left:1.2rem}}.md-content__inner:before{content:"";display:block;height:.4rem}.md-content__inner>:last-child{margin-bottom:0}[dir=ltr] .md-content__button{float:right}[dir=rtl] .md-content__button{float:left}[dir=ltr] .md-content__button{margin-left:.4rem}[dir=rtl] .md-content__button{margin-right:.4rem}.md-content__button{margin:.4rem 0;padding:0}@media print{.md-content__button{display:none}}.md-typeset .md-content__button{color:var(--md-default-fg-color--lighter)}.md-content__button svg{display:inline;vertical-align:top}[dir=rtl] .md-content__button svg{transform:scaleX(-1)}[dir=ltr] .md-dialog{right:.8rem}[dir=rtl] .md-dialog{left:.8rem}.md-dialog{background-color:var(--md-default-fg-color);border-radius:.1rem;bottom:.8rem;box-shadow:var(--md-shadow-z3);min-width:11.1rem;opacity:0;padding:.4rem .6rem;pointer-events:none;position:fixed;transform:translateY(100%);transition:transform 0ms .4s,opacity .4s;z-index:4}@media print{.md-dialog{display:none}}.md-dialog--active{opacity:1;pointer-events:auto;transform:translateY(0);transition:transform .4s cubic-bezier(.075,.85,.175,1),opacity .4s}.md-dialog__inner{color:var(--md-default-bg-color);font-size:.7rem}.md-feedback{margin:2em 0 1em;text-align:center}.md-feedback fieldset{border:none;margin:0;padding:0}.md-feedback__title{font-weight:700;margin:1em auto}.md-feedback__inner{position:relative}.md-feedback__list{align-content:baseline;display:flex;flex-wrap:wrap;justify-content:center;position:relative}.md-feedback__list:hover .md-icon:not(:disabled){color:var(--md-default-fg-color--lighter)}:disabled .md-feedback__list{min-height:1.8rem}.md-feedback__icon{color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;margin:0 .1rem;transition:color 125ms}.md-feedback__icon:not(:disabled).md-icon:hover{color:var(--md-accent-fg-color)}.md-feedback__icon:disabled{color:var(--md-default-fg-color--lightest);pointer-events:none}.md-feedback__note{opacity:0;position:relative;transform:translateY(.4rem);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-feedback__note>*{margin:0 auto;max-width:16rem}:disabled .md-feedback__note{opacity:1;transform:translateY(0)}.md-footer{background-color:var(--md-footer-bg-color);color:var(--md-footer-fg-color)}@media print{.md-footer{display:none}}.md-footer__inner{justify-content:space-between;overflow:auto;padding:.2rem}.md-footer__inner:not([hidden]){display:flex}.md-footer__link{display:flex;flex-grow:0.01;outline-color:var(--md-accent-fg-color);overflow:hidden;padding-bottom:.4rem;padding-top:1.4rem;transition:opacity .25s}.md-footer__link:-webkit-any(:focus,:hover){opacity:.7}.md-footer__link:-moz-any(:focus,:hover){opacity:.7}.md-footer__link:is(:focus,:hover){opacity:.7}[dir=rtl] .md-footer__link svg{transform:scaleX(-1)}@media screen and (max-width:44.9375em){.md-footer__link--prev .md-footer__title{display:none}}[dir=ltr] .md-footer__link--next{margin-left:auto}[dir=rtl] .md-footer__link--next{margin-right:auto}.md-footer__link--next{text-align:right}[dir=rtl] .md-footer__link--next{text-align:left}.md-footer__title{flex-grow:1;font-size:.9rem;line-height:2.4rem;max-width:calc(100% - 2.4rem);padding:0 1rem;position:relative;white-space:nowrap}.md-footer__button{margin:.2rem;padding:.4rem}.md-footer__direction{font-size:.64rem;left:0;margin-top:-1rem;opacity:.7;padding:0 1rem;position:absolute;right:0}.md-footer-meta{background-color:var(--md-footer-bg-color--dark)}.md-footer-meta__inner{display:flex;flex-wrap:wrap;justify-content:space-between;padding:.2rem}html .md-footer-meta.md-typeset a{color:var(--md-footer-fg-color--light)}html .md-footer-meta.md-typeset a:-webkit-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:-moz-any(:focus,:hover){color:var(--md-footer-fg-color)}html .md-footer-meta.md-typeset a:is(:focus,:hover){color:var(--md-footer-fg-color)}.md-copyright{color:var(--md-footer-fg-color--lighter);font-size:.64rem;margin:auto .6rem;padding:.4rem 0;width:100%}@media screen and (min-width:45em){.md-copyright{width:auto}}.md-copyright__highlight{color:var(--md-footer-fg-color--light)}.md-social{margin:0 .4rem;padding:.2rem 0 .6rem}@media screen and (min-width:45em){.md-social{padding:.6rem 0}}.md-social__link{display:inline-block;height:1.6rem;text-align:center;width:1.6rem}.md-social__link:before{line-height:1.9}.md-social__link svg{fill:currentcolor;max-height:.8rem;vertical-align:-25%}.md-typeset .md-button{border:.1rem solid;border-radius:.1rem;color:var(--md-primary-fg-color);cursor:pointer;display:inline-block;font-weight:700;padding:.625em 2em;transition:color 125ms,background-color 125ms,border-color 125ms}.md-typeset .md-button--primary{background-color:var(--md-primary-fg-color);border-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color)}.md-typeset .md-button:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-typeset .md-button:is(:focus,:hover){background-color:var(--md-accent-fg-color);border-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[dir=ltr] .md-typeset .md-input{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .md-input,[dir=rtl] .md-typeset .md-input{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .md-input{border-top-left-radius:.1rem}.md-typeset .md-input{border-bottom:.1rem solid var(--md-default-fg-color--lighter);box-shadow:var(--md-shadow-z1);font-size:.8rem;height:1.8rem;padding:0 .6rem;transition:border .25s,box-shadow .25s}.md-typeset .md-input:-webkit-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:-moz-any(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input:is(:focus,:hover){border-bottom-color:var(--md-accent-fg-color);box-shadow:var(--md-shadow-z2)}.md-typeset .md-input--stretch{width:100%}.md-header{background-color:var(--md-primary-fg-color);box-shadow:0 0 .2rem #0000,0 .2rem .4rem #0000;color:var(--md-primary-bg-color);display:block;left:0;position:-webkit-sticky;position:sticky;right:0;top:0;z-index:4}@media print{.md-header{display:none}}.md-header[hidden]{transform:translateY(-100%);transition:transform .25s cubic-bezier(.8,0,.6,1),box-shadow .25s}.md-header--shadow{box-shadow:0 0 .2rem #0000001a,0 .2rem .4rem #0003;transition:transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}.md-header__inner{align-items:center;display:flex;padding:0 .2rem}.md-header__button{color:currentcolor;cursor:pointer;margin:.2rem;outline-color:var(--md-accent-fg-color);padding:.4rem;position:relative;transition:opacity .25s;vertical-align:middle;z-index:1}.md-header__button:hover{opacity:.7}.md-header__button:not([hidden]){display:inline-block}.md-header__button:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}.md-header__button.md-logo{margin:.2rem;padding:.4rem}@media screen and (max-width:76.1875em){.md-header__button.md-logo{display:none}}.md-header__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}.md-header__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:1.2rem;width:auto}@media screen and (min-width:60em){.md-header__button[for=__search]{display:none}}.no-js .md-header__button[for=__search]{display:none}[dir=rtl] .md-header__button[for=__search] svg{transform:scaleX(-1)}@media screen and (min-width:76.25em){.md-header__button[for=__drawer]{display:none}}.md-header__topic{display:flex;max-width:100%;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;white-space:nowrap}.md-header__topic+.md-header__topic{opacity:0;pointer-events:none;transform:translateX(1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__topic+.md-header__topic{transform:translateX(-1.25rem)}.md-header__topic:first-child{font-weight:700}[dir=ltr] .md-header__title{margin-right:.4rem}[dir=rtl] .md-header__title{margin-left:.4rem}[dir=ltr] .md-header__title{margin-left:1rem}[dir=rtl] .md-header__title{margin-right:1rem}.md-header__title{flex-grow:1;font-size:.9rem;height:2.4rem;line-height:2.4rem}.md-header__title--active .md-header__topic{opacity:0;pointer-events:none;transform:translateX(-1.25rem);transition:transform .4s cubic-bezier(1,.7,.1,.1),opacity .15s;z-index:-1}[dir=rtl] .md-header__title--active .md-header__topic{transform:translateX(1.25rem)}.md-header__title--active .md-header__topic+.md-header__topic{opacity:1;pointer-events:auto;transform:translateX(0);transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .15s;z-index:0}.md-header__title>.md-header__ellipsis{height:100%;position:relative;width:100%}.md-header__option{display:flex;flex-shrink:0;max-width:100%;transition:max-width 0ms .25s,opacity .25s .25s;white-space:nowrap}[data-md-toggle=search]:checked~.md-header .md-header__option{max-width:0;opacity:0;transition:max-width 0ms,opacity 0ms}.md-header__source{display:none}@media screen and (min-width:60em){[dir=ltr] .md-header__source{margin-left:1rem}[dir=rtl] .md-header__source{margin-right:1rem}.md-header__source{display:block;max-width:11.7rem;width:11.7rem}}@media screen and (min-width:76.25em){[dir=ltr] .md-header__source{margin-left:1.4rem}[dir=rtl] .md-header__source{margin-right:1.4rem}}:root{--md-nav-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-nav-icon--next:url('data:image/svg+xml;charset=utf-8,');--md-toc-icon:url('data:image/svg+xml;charset=utf-8,')}.md-nav{font-size:.7rem;line-height:1.3}.md-nav__title{display:block;font-weight:700;overflow:hidden;padding:0 .6rem;text-overflow:ellipsis}.md-nav__title .md-nav__button{display:none}.md-nav__title .md-nav__button img{height:100%;width:auto}.md-nav__title .md-nav__button.md-logo :-webkit-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :-moz-any(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__title .md-nav__button.md-logo :is(img,svg){fill:currentcolor;display:block;height:2.4rem;max-width:100%;object-fit:contain;width:auto}.md-nav__list{list-style:none;margin:0;padding:0}.md-nav__item{padding:0 .6rem}[dir=ltr] .md-nav__item .md-nav__item{padding-right:0}[dir=rtl] .md-nav__item .md-nav__item{padding-left:0}.md-nav__link{align-items:center;cursor:pointer;display:flex;justify-content:space-between;margin-top:.625em;overflow:hidden;scroll-snap-align:start;text-overflow:ellipsis;transition:color 125ms}.md-nav__link--passed{color:var(--md-default-fg-color--light)}.md-nav__item .md-nav__link--active{color:var(--md-typeset-a-color)}.md-nav__item .md-nav__link--index [href]{width:100%}.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav__link.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-nav--primary .md-nav__link[for=__toc]{display:none}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{background-color:currentcolor;display:block;height:100%;-webkit-mask-image:var(--md-toc-icon);mask-image:var(--md-toc-icon);width:100%}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:none}.md-nav__link>*{cursor:pointer;display:flex}.md-nav__icon{flex-shrink:0}.md-nav__source{display:none}@media screen and (max-width:76.1875em){.md-nav--primary,.md-nav--primary .md-nav{background-color:var(--md-default-bg-color);display:flex;flex-direction:column;height:100%;left:0;position:absolute;right:0;top:0;z-index:1}.md-nav--primary :-webkit-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :-moz-any(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary :is(.md-nav__title,.md-nav__item){font-size:.8rem;line-height:1.5}.md-nav--primary .md-nav__title{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);cursor:pointer;height:5.6rem;line-height:2.4rem;padding:3rem .8rem .2rem;position:relative;white-space:nowrap}[dir=ltr] .md-nav--primary .md-nav__title .md-nav__icon{left:.4rem}[dir=rtl] .md-nav--primary .md-nav__title .md-nav__icon{right:.4rem}.md-nav--primary .md-nav__title .md-nav__icon{display:block;height:1.2rem;margin:.2rem;position:absolute;top:.4rem;width:1.2rem}.md-nav--primary .md-nav__title .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--prev);mask-image:var(--md-nav-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}.md-nav--primary .md-nav__title~.md-nav__list{background-color:var(--md-default-bg-color);box-shadow:0 .05rem 0 var(--md-default-fg-color--lightest) inset;overflow-y:auto;scroll-snap-type:y mandatory;touch-action:pan-y}.md-nav--primary .md-nav__title~.md-nav__list>:first-child{border-top:0}.md-nav--primary .md-nav__title[for=__drawer]{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);font-weight:700}.md-nav--primary .md-nav__title .md-logo{display:block;left:.2rem;margin:.2rem;padding:.4rem;position:absolute;right:.2rem;top:.2rem}.md-nav--primary .md-nav__list{flex:1}.md-nav--primary .md-nav__item{border-top:.05rem solid var(--md-default-fg-color--lightest);padding:0}.md-nav--primary .md-nav__item--active>.md-nav__link{color:var(--md-typeset-a-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__item--active>.md-nav__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-nav--primary .md-nav__link{margin-top:0;padding:.6rem .8rem}[dir=ltr] .md-nav--primary .md-nav__link .md-nav__icon{margin-right:-.2rem}[dir=rtl] .md-nav--primary .md-nav__link .md-nav__icon{margin-left:-.2rem}.md-nav--primary .md-nav__link .md-nav__icon{font-size:1.2rem;height:1.2rem;width:1.2rem}.md-nav--primary .md-nav__link .md-nav__icon:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-nav--primary .md-nav__icon:after{transform:scale(-1)}.md-nav--primary .md-nav--secondary .md-nav{background-color:initial;position:static}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:1.4rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-right:1.4rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-right:2rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:2.6rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-right:2.6rem}[dir=ltr] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:3.2rem}[dir=rtl] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-right:3.2rem}.md-nav--secondary{background-color:initial}.md-nav__toggle~.md-nav{display:flex;opacity:0;transform:translateX(100%);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity 125ms 50ms}[dir=rtl] .md-nav__toggle~.md-nav{transform:translateX(-100%)}.md-nav__toggle:checked~.md-nav{opacity:1;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity 125ms 125ms}.md-nav__toggle:checked~.md-nav>.md-nav__list{-webkit-backface-visibility:hidden;backface-visibility:hidden}}@media screen and (max-width:59.9375em){.md-nav--primary .md-nav__link[for=__toc]{display:flex}.md-nav--primary .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--primary .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--primary .md-nav__link[for=__toc]~.md-nav{display:flex}.md-nav__source{background-color:var(--md-primary-fg-color--dark);color:var(--md-primary-bg-color);display:block;padding:0 .2rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-nav--integrated .md-nav__link[for=__toc]{display:flex}.md-nav--integrated .md-nav__link[for=__toc] .md-icon:after{content:""}.md-nav--integrated .md-nav__link[for=__toc]+.md-nav__link{display:none}.md-nav--integrated .md-nav__link[for=__toc]~.md-nav{display:flex}}@media screen and (min-width:60em){.md-nav--secondary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--secondary .md-nav__title[for=__toc]{scroll-snap-align:start}.md-nav--secondary .md-nav__title .md-nav__icon{display:none}}@media screen and (min-width:76.25em){.md-nav{transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav--primary .md-nav__title{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--primary .md-nav__title[for=__drawer]{scroll-snap-align:start}.md-nav--primary .md-nav__title .md-nav__icon,.md-nav__toggle~.md-nav{display:none}.md-nav__toggle:-webkit-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:-moz-any(:checked,:indeterminate)~.md-nav{display:block}.md-nav__toggle:is(:checked,:indeterminate)~.md-nav{display:block}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--section{display:block;margin:1.25em 0}.md-nav__item--section:last-child{margin-bottom:0}.md-nav__item--section>.md-nav__link{font-weight:700;pointer-events:none}.md-nav__item--section>.md-nav__link--index [href]{pointer-events:auto}.md-nav__item--section>.md-nav__link .md-nav__icon{display:none}.md-nav__item--section>.md-nav{display:block}.md-nav__item--section>.md-nav>.md-nav__list>.md-nav__item{padding:0}.md-nav__icon{border-radius:100%;height:.9rem;transition:background-color .25s,transform .25s;width:.9rem}[dir=rtl] .md-nav__icon{transform:rotate(180deg)}.md-nav__icon:hover{background-color:var(--md-accent-fg-color--transparent)}.md-nav__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-nav-icon--next);mask-image:var(--md-nav-icon--next);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:-.1rem;width:100%}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link .md-nav__icon,.md-nav__item--nested .md-nav__toggle:indeterminate~.md-nav__link .md-nav__icon{transform:rotate(90deg)}.md-nav--lifted>.md-nav__list>.md-nav__item,.md-nav--lifted>.md-nav__list>.md-nav__item--nested,.md-nav--lifted>.md-nav__title{display:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active{display:block;padding:0}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link{background:var(--md-default-bg-color);box-shadow:0 0 .4rem .4rem var(--md-default-bg-color);font-weight:700;margin-top:0;padding:0 .6rem;position:-webkit-sticky;position:sticky;top:0;z-index:1}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link:not(.md-nav__link--index){pointer-events:none}.md-nav--lifted>.md-nav__list>.md-nav__item--active>.md-nav__link .md-nav__icon{display:none}.md-nav--lifted .md-nav[data-md-level="1"]{display:block}[dir=ltr] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-right:.6rem}[dir=rtl] .md-nav--lifted .md-nav[data-md-level="1"]>.md-nav__list>.md-nav__item{padding-left:.6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested){padding:0 .6rem}.md-nav--integrated>.md-nav__list>.md-nav__item--active:not(.md-nav__item--nested)>.md-nav__link{padding:0}[dir=ltr] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-left:.05rem solid var(--md-primary-fg-color)}[dir=rtl] .md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{border-right:.05rem solid var(--md-primary-fg-color)}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary{display:block;margin-bottom:1.25em}.md-nav--integrated>.md-nav__list>.md-nav__item--active .md-nav--secondary>.md-nav__title{display:none}}:root{--md-search-result-icon:url('data:image/svg+xml;charset=utf-8,')}.md-search{position:relative}@media screen and (min-width:60em){.md-search{padding:.2rem 0}}.no-js .md-search{display:none}.md-search__overlay{opacity:0;z-index:1}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__overlay{left:-2.2rem}[dir=rtl] .md-search__overlay{right:-2.2rem}.md-search__overlay{background-color:var(--md-default-bg-color);border-radius:1rem;height:2rem;overflow:hidden;pointer-events:none;position:absolute;top:-1rem;transform-origin:center;transition:transform .3s .1s,opacity .2s .2s;width:2rem}[data-md-toggle=search]:checked~.md-header .md-search__overlay{opacity:1;transition:transform .4s,opacity .1s}}@media screen and (min-width:60em){[dir=ltr] .md-search__overlay{left:0}[dir=rtl] .md-search__overlay{right:0}.md-search__overlay{background-color:#0000008a;cursor:pointer;height:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0}[data-md-toggle=search]:checked~.md-header .md-search__overlay{height:200vh;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@media screen and (max-width:29.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(45)}}@media screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(60)}}@media screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{transform:scale(75)}}.md-search__inner{-webkit-backface-visibility:hidden;backface-visibility:hidden}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__inner{left:0}[dir=rtl] .md-search__inner{right:0}.md-search__inner{height:0;opacity:0;overflow:hidden;position:fixed;top:0;transform:translateX(5%);transition:width 0ms .3s,height 0ms .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;width:0;z-index:2}[dir=rtl] .md-search__inner{transform:translateX(-5%)}[data-md-toggle=search]:checked~.md-header .md-search__inner{height:100%;opacity:1;transform:translateX(0);transition:width 0ms 0ms,height 0ms 0ms,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__inner{float:right}[dir=rtl] .md-search__inner{float:left}.md-search__inner{padding:.1rem 0;position:relative;transition:width .25s cubic-bezier(.1,.7,.1,1);width:11.7rem}}@media screen and (min-width:60em) and (max-width:76.1875em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:23.4rem}}@media screen and (min-width:76.25em){[data-md-toggle=search]:checked~.md-header .md-search__inner{width:34.4rem}}.md-search__form{background-color:var(--md-default-bg-color);box-shadow:0 0 .6rem #0000;height:2.4rem;position:relative;transition:color .25s,background-color .25s;z-index:2}@media screen and (min-width:60em){.md-search__form{background-color:#00000042;border-radius:.1rem;height:1.8rem}.md-search__form:hover{background-color:#ffffff1f}}[data-md-toggle=search]:checked~.md-header .md-search__form{background-color:var(--md-default-bg-color);border-radius:.1rem .1rem 0 0;box-shadow:0 0 .6rem #00000012;color:var(--md-default-fg-color)}[dir=ltr] .md-search__input{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__input{padding-left:2.2rem;padding-right:3.6rem}.md-search__input{background:#0000;font-size:.9rem;height:100%;position:relative;text-overflow:ellipsis;width:100%;z-index:2}.md-search__input::placeholder{transition:color .25s}.md-search__input::placeholder,.md-search__input~.md-search__icon{color:var(--md-default-fg-color--light)}.md-search__input::-ms-clear{display:none}@media screen and (max-width:59.9375em){.md-search__input{font-size:.9rem;height:2.4rem;width:100%}}@media screen and (min-width:60em){[dir=ltr] .md-search__input{padding-left:2.2rem}[dir=rtl] .md-search__input{padding-right:2.2rem}.md-search__input{color:inherit;font-size:.8rem}.md-search__input::placeholder{color:var(--md-primary-bg-color--light)}.md-search__input+.md-search__icon{color:var(--md-primary-bg-color)}[data-md-toggle=search]:checked~.md-header .md-search__input{text-overflow:clip}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:var(--md-default-fg-color--light)}}.md-search__icon{cursor:pointer;display:inline-block;height:1.2rem;transition:color .25s,opacity .25s;width:1.2rem}.md-search__icon:hover{opacity:.7}[dir=ltr] .md-search__icon[for=__search]{left:.5rem}[dir=rtl] .md-search__icon[for=__search]{right:.5rem}.md-search__icon[for=__search]{position:absolute;top:.3rem;z-index:2}[dir=rtl] .md-search__icon[for=__search] svg{transform:scaleX(-1)}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__icon[for=__search]{left:.8rem}[dir=rtl] .md-search__icon[for=__search]{right:.8rem}.md-search__icon[for=__search]{top:.6rem}.md-search__icon[for=__search] svg:first-child{display:none}}@media screen and (min-width:60em){.md-search__icon[for=__search]{pointer-events:none}.md-search__icon[for=__search] svg:last-child{display:none}}[dir=ltr] .md-search__options{right:.5rem}[dir=rtl] .md-search__options{left:.5rem}.md-search__options{pointer-events:none;position:absolute;top:.3rem;z-index:2}@media screen and (max-width:59.9375em){[dir=ltr] .md-search__options{right:.8rem}[dir=rtl] .md-search__options{left:.8rem}.md-search__options{top:.6rem}}[dir=ltr] .md-search__options>*{margin-left:.2rem}[dir=rtl] .md-search__options>*{margin-right:.2rem}.md-search__options>*{color:var(--md-default-fg-color--light);opacity:0;transform:scale(.75);transition:transform .15s cubic-bezier(.1,.7,.1,1),opacity .15s}.md-search__options>:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>*{opacity:1;pointer-events:auto;transform:scale(1)}[data-md-toggle=search]:checked~.md-header .md-search__input:valid~.md-search__options>:hover{opacity:.7}[dir=ltr] .md-search__suggest{padding-left:3.6rem;padding-right:2.2rem}[dir=rtl] .md-search__suggest{padding-left:2.2rem;padding-right:3.6rem}.md-search__suggest{align-items:center;color:var(--md-default-fg-color--lighter);display:flex;font-size:.9rem;height:100%;opacity:0;position:absolute;top:0;transition:opacity 50ms;white-space:nowrap;width:100%}@media screen and (min-width:60em){[dir=ltr] .md-search__suggest{padding-left:2.2rem}[dir=rtl] .md-search__suggest{padding-right:2.2rem}.md-search__suggest{font-size:.8rem}}[data-md-toggle=search]:checked~.md-header .md-search__suggest{opacity:1;transition:opacity .3s .1s}[dir=ltr] .md-search__output{border-bottom-left-radius:.1rem}[dir=ltr] .md-search__output,[dir=rtl] .md-search__output{border-bottom-right-radius:.1rem}[dir=rtl] .md-search__output{border-bottom-left-radius:.1rem}.md-search__output{overflow:hidden;position:absolute;width:100%;z-index:1}@media screen and (max-width:59.9375em){.md-search__output{bottom:0;top:2.4rem}}@media screen and (min-width:60em){.md-search__output{opacity:0;top:1.9rem;transition:opacity .4s}[data-md-toggle=search]:checked~.md-header .md-search__output{box-shadow:var(--md-shadow-z3);opacity:1}}.md-search__scrollwrap{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);height:100%;overflow-y:auto;touch-action:pan-y}@media (-webkit-max-device-pixel-ratio:1),(max-resolution:1dppx){.md-search__scrollwrap{transform:translateZ(0)}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap{width:23.4rem}}@media screen and (min-width:76.25em){.md-search__scrollwrap{width:34.4rem}}@media screen and (min-width:60em){.md-search__scrollwrap{max-height:0;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-search__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}}.md-search-result{color:var(--md-default-fg-color);word-break:break-word}.md-search-result__meta{background-color:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--light);font-size:.64rem;line-height:1.8rem;padding:0 .8rem;scroll-snap-align:start}@media screen and (min-width:60em){[dir=ltr] .md-search-result__meta{padding-left:2.2rem}[dir=rtl] .md-search-result__meta{padding-right:2.2rem}}.md-search-result__list{list-style:none;margin:0;padding:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.md-search-result__item{box-shadow:0 -.05rem var(--md-default-fg-color--lightest)}.md-search-result__item:first-child{box-shadow:none}.md-search-result__link{display:block;outline:none;scroll-snap-align:start;transition:background-color .25s}.md-search-result__link:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent)}.md-search-result__link:last-child p:last-child{margin-bottom:.6rem}.md-search-result__more summary{color:var(--md-typeset-a-color);cursor:pointer;display:block;font-size:.64rem;outline:none;padding:.75em .8rem;scroll-snap-align:start;transition:color .25s,background-color .25s}@media screen and (min-width:60em){[dir=ltr] .md-search-result__more summary{padding-left:2.2rem}[dir=rtl] .md-search-result__more summary{padding-right:2.2rem}}.md-search-result__more summary:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary:is(:focus,:hover){background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-search-result__more summary::marker{display:none}.md-search-result__more summary::-webkit-details-marker{display:none}.md-search-result__more summary~*>*{opacity:.65}.md-search-result__article{overflow:hidden;padding:0 .8rem;position:relative}@media screen and (min-width:60em){[dir=ltr] .md-search-result__article{padding-left:2.2rem}[dir=rtl] .md-search-result__article{padding-right:2.2rem}}.md-search-result__article--document .md-search-result__title{font-size:.8rem;font-weight:400;line-height:1.4;margin:.55rem 0}[dir=ltr] .md-search-result__icon{left:0}[dir=rtl] .md-search-result__icon{right:0}.md-search-result__icon{color:var(--md-default-fg-color--light);height:1.2rem;margin:.5rem;position:absolute;width:1.2rem}@media screen and (max-width:59.9375em){.md-search-result__icon{display:none}}.md-search-result__icon:after{background-color:currentcolor;content:"";display:inline-block;height:100%;-webkit-mask-image:var(--md-search-result-icon);mask-image:var(--md-search-result-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:100%}[dir=rtl] .md-search-result__icon:after{transform:scaleX(-1)}.md-search-result__title{font-size:.64rem;font-weight:700;line-height:1.6;margin:.5em 0}.md-search-result__teaser{-webkit-box-orient:vertical;-webkit-line-clamp:2;color:var(--md-default-fg-color--light);display:-webkit-box;font-size:.64rem;line-height:1.6;margin:.5em 0;max-height:2rem;overflow:hidden;text-overflow:ellipsis}@media screen and (max-width:44.9375em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}@media screen and (min-width:60em) and (max-width:76.1875em){.md-search-result__teaser{-webkit-line-clamp:3;max-height:3rem}}.md-search-result__teaser mark{background-color:initial;text-decoration:underline}.md-search-result__terms{font-size:.64rem;font-style:italic;margin:.5em 0}.md-search-result mark{background-color:initial;color:var(--md-accent-fg-color)}.md-select{position:relative;z-index:1}.md-select__inner{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);left:50%;margin-top:.2rem;max-height:0;opacity:0;position:absolute;top:calc(100% - .2rem);transform:translate3d(-50%,.3rem,0);transition:transform .25s 375ms,opacity .25s .25s,max-height 0ms .5s}.md-select:-webkit-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-webkit-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:-moz-any(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);-moz-transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms;transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select:is(:focus-within,:hover) .md-select__inner{max-height:10rem;opacity:1;transform:translate3d(-50%,0,0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,max-height 0ms}.md-select__inner:after{border-bottom:.2rem solid #0000;border-bottom-color:var(--md-default-bg-color);border-left:.2rem solid #0000;border-right:.2rem solid #0000;border-top:0;content:"";height:0;left:50%;margin-left:-.2rem;margin-top:-.2rem;position:absolute;top:0;width:0}.md-select__list{border-radius:.1rem;font-size:.8rem;list-style-type:none;margin:0;max-height:inherit;overflow:auto;padding:0}.md-select__item{line-height:1.8rem}[dir=ltr] .md-select__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-select__link{padding-left:1.2rem;padding-right:.6rem}.md-select__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:background-color .25s,color .25s;width:100%}.md-select__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-select__link:focus{background-color:var(--md-default-fg-color--lightest)}.md-sidebar{align-self:flex-start;flex-shrink:0;padding:1.2rem 0;position:-webkit-sticky;position:sticky;top:2.4rem;width:12.1rem}@media print{.md-sidebar{display:none}}@media screen and (max-width:76.1875em){[dir=ltr] .md-sidebar--primary{left:-12.1rem}[dir=rtl] .md-sidebar--primary{right:-12.1rem}.md-sidebar--primary{background-color:var(--md-default-bg-color);display:block;height:100%;position:fixed;top:0;transform:translateX(0);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;width:12.1rem;z-index:5}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:var(--md-shadow-z3);transform:translateX(12.1rem)}[dir=rtl] [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{transform:translateX(-12.1rem)}.md-sidebar--primary .md-sidebar__scrollwrap{bottom:0;left:0;margin:0;overflow:hidden;position:absolute;right:0;scroll-snap-type:none;top:0}}@media screen and (min-width:76.25em){.md-sidebar{height:0}.no-js .md-sidebar{height:auto}.md-header--lifted~.md-container .md-sidebar{top:4.8rem}}.md-sidebar--secondary{display:none;order:2}@media screen and (min-width:60em){.md-sidebar--secondary{height:0}.no-js .md-sidebar--secondary{height:auto}.md-sidebar--secondary:not([hidden]){display:block}.md-sidebar--secondary .md-sidebar__scrollwrap{touch-action:pan-y}}.md-sidebar__scrollwrap{scrollbar-gutter:stable;-webkit-backface-visibility:hidden;backface-visibility:hidden;margin:0 .2rem;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) #0000;scrollbar-width:thin}.md-sidebar__scrollwrap:hover{scrollbar-color:var(--md-accent-fg-color) #0000}.md-sidebar__scrollwrap::-webkit-scrollbar{height:.2rem;width:.2rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}@supports selector(::-webkit-scrollbar){.md-sidebar__scrollwrap{scrollbar-gutter:auto}[dir=ltr] .md-sidebar__inner{padding-right:calc(100% - 11.5rem)}[dir=rtl] .md-sidebar__inner{padding-left:calc(100% - 11.5rem)}}@media screen and (max-width:76.1875em){.md-overlay{background-color:#0000008a;height:0;opacity:0;position:fixed;top:0;transition:width 0ms .25s,height 0ms .25s,opacity .25s;width:0;z-index:5}[data-md-toggle=drawer]:checked~.md-overlay{height:100%;opacity:1;transition:width 0ms,height 0ms,opacity .25s;width:100%}}@keyframes facts{0%{height:0}to{height:.65rem}}@keyframes fact{0%{opacity:0;transform:translateY(100%)}50%{opacity:0}to{opacity:1;transform:translateY(0)}}:root{--md-source-forks-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-repositories-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-stars-icon:url('data:image/svg+xml;charset=utf-8,');--md-source-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-source{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.65rem;line-height:1.2;outline-color:var(--md-accent-fg-color);transition:opacity .25s;white-space:nowrap}.md-source:hover{opacity:.7}.md-source__icon{display:inline-block;height:2.4rem;vertical-align:middle;width:2rem}[dir=ltr] .md-source__icon svg{margin-left:.6rem}[dir=rtl] .md-source__icon svg{margin-right:.6rem}.md-source__icon svg{margin-top:.6rem}[dir=ltr] .md-source__icon+.md-source__repository{margin-left:-2rem}[dir=rtl] .md-source__icon+.md-source__repository{margin-right:-2rem}[dir=ltr] .md-source__icon+.md-source__repository{padding-left:2rem}[dir=rtl] .md-source__icon+.md-source__repository{padding-right:2rem}[dir=ltr] .md-source__repository{margin-left:.6rem}[dir=rtl] .md-source__repository{margin-right:.6rem}.md-source__repository{display:inline-block;max-width:calc(100% - 1.2rem);overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.md-source__facts{display:flex;font-size:.55rem;gap:.4rem;list-style-type:none;margin:.1rem 0 0;opacity:.75;overflow:hidden;padding:0;width:100%}.md-source__repository--active .md-source__facts{animation:facts .25s ease-in}.md-source__fact{overflow:hidden;text-overflow:ellipsis}.md-source__repository--active .md-source__fact{animation:fact .4s ease-out}[dir=ltr] .md-source__fact:before{margin-right:.1rem}[dir=rtl] .md-source__fact:before{margin-left:.1rem}.md-source__fact:before{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;vertical-align:text-top;width:.6rem}.md-source__fact:nth-child(1n+2){flex-shrink:0}.md-source__fact--version:before{-webkit-mask-image:var(--md-source-version-icon);mask-image:var(--md-source-version-icon)}.md-source__fact--stars:before{-webkit-mask-image:var(--md-source-stars-icon);mask-image:var(--md-source-stars-icon)}.md-source__fact--forks:before{-webkit-mask-image:var(--md-source-forks-icon);mask-image:var(--md-source-forks-icon)}.md-source__fact--repositories:before{-webkit-mask-image:var(--md-source-repositories-icon);mask-image:var(--md-source-repositories-icon)}.md-tabs{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block;line-height:1.3;overflow:auto;width:100%;z-index:3}@media print{.md-tabs{display:none}}@media screen and (max-width:76.1875em){.md-tabs{display:none}}.md-tabs[hidden]{pointer-events:none}[dir=ltr] .md-tabs__list{margin-left:.2rem}[dir=rtl] .md-tabs__list{margin-right:.2rem}.md-tabs__list{contain:content;list-style:none;margin:0;padding:0;white-space:nowrap}.md-tabs__item{display:inline-block;height:2.4rem;padding-left:.6rem;padding-right:.6rem}.md-tabs__link{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;font-size:.7rem;margin-top:.8rem;opacity:.7;outline-color:var(--md-accent-fg-color);outline-offset:.2rem;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s}.md-tabs__link--active,.md-tabs__link:-webkit-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:-moz-any(:focus,:hover){color:inherit;opacity:1}.md-tabs__link--active,.md-tabs__link:is(:focus,:hover){color:inherit;opacity:1}.md-tabs__item:nth-child(2) .md-tabs__link{transition-delay:20ms}.md-tabs__item:nth-child(3) .md-tabs__link{transition-delay:40ms}.md-tabs__item:nth-child(4) .md-tabs__link{transition-delay:60ms}.md-tabs__item:nth-child(5) .md-tabs__link{transition-delay:80ms}.md-tabs__item:nth-child(6) .md-tabs__link{transition-delay:.1s}.md-tabs__item:nth-child(7) .md-tabs__link{transition-delay:.12s}.md-tabs__item:nth-child(8) .md-tabs__link{transition-delay:.14s}.md-tabs__item:nth-child(9) .md-tabs__link{transition-delay:.16s}.md-tabs__item:nth-child(10) .md-tabs__link{transition-delay:.18s}.md-tabs__item:nth-child(11) .md-tabs__link{transition-delay:.2s}.md-tabs__item:nth-child(12) .md-tabs__link{transition-delay:.22s}.md-tabs__item:nth-child(13) .md-tabs__link{transition-delay:.24s}.md-tabs__item:nth-child(14) .md-tabs__link{transition-delay:.26s}.md-tabs__item:nth-child(15) .md-tabs__link{transition-delay:.28s}.md-tabs__item:nth-child(16) .md-tabs__link{transition-delay:.3s}.md-tabs[hidden] .md-tabs__link{opacity:0;transform:translateY(50%);transition:transform 0ms .1s,opacity .1s}:root{--md-tag-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .md-tags{margin-bottom:.75em;margin-top:-.125em}[dir=ltr] .md-typeset .md-tag{margin-right:.5em}[dir=rtl] .md-typeset .md-tag{margin-left:.5em}.md-typeset .md-tag{background:var(--md-default-fg-color--lightest);border-radius:2.4rem;display:inline-block;font-size:.64rem;font-weight:700;letter-spacing:normal;line-height:1.6;margin-bottom:.5em;padding:.3125em .9375em;vertical-align:middle}.md-typeset .md-tag[href]{-webkit-tap-highlight-color:transparent;color:inherit;outline:none;transition:color 125ms,background-color 125ms}.md-typeset .md-tag[href]:focus,.md-typeset .md-tag[href]:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}[id]>.md-typeset .md-tag{vertical-align:text-top}.md-typeset .md-tag-icon:before{background-color:var(--md-default-fg-color--lighter);content:"";display:inline-block;height:1.2em;margin-right:.4em;-webkit-mask-image:var(--md-tag-icon);mask-image:var(--md-tag-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color 125ms;vertical-align:text-bottom;width:1.2em}.md-typeset .md-tag-icon:-webkit-any(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}.md-typeset .md-tag-icon:-moz-any(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}.md-typeset .md-tag-icon:is(a:focus,a:hover):before{background-color:var(--md-accent-bg-color)}@keyframes pulse{0%{box-shadow:0 0 0 0 var(--md-default-fg-color--lightest);transform:scale(.95)}75%{box-shadow:0 0 0 .625em #0000;transform:scale(1)}to{box-shadow:0 0 0 0 #0000;transform:scale(.95)}}:root{--md-tooltip-width:20rem}.md-tooltip{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);font-family:var(--md-text-font-family);left:clamp(var(--md-tooltip-0,0rem) + .8rem,var(--md-tooltip-x),100vw + var(--md-tooltip-0,0rem) + .8rem - var(--md-tooltip-width) - 2 * .8rem);max-width:calc(100vw - 1.6rem);opacity:0;position:absolute;top:var(--md-tooltip-y);transform:translateY(-.4rem);transition:transform 0ms .25s,opacity .25s,z-index .25s;width:var(--md-tooltip-width);z-index:0}.md-tooltip--active{opacity:1;transform:translateY(0);transition:transform .25s cubic-bezier(.1,.7,.1,1),opacity .25s,z-index 0ms;z-index:2}:-webkit-any(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}:-moz-any(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}:is(.focus-visible>.md-tooltip,.md-tooltip:target){outline:var(--md-accent-fg-color) auto}.md-tooltip__inner{font-size:.64rem;padding:.8rem}.md-tooltip__inner.md-typeset>:first-child{margin-top:0}.md-tooltip__inner.md-typeset>:last-child{margin-bottom:0}.md-annotation{font-weight:400;outline:none;white-space:normal}[dir=rtl] .md-annotation{direction:rtl}.md-annotation:not([hidden]){display:inline-block;line-height:1.325}.md-annotation__index{cursor:pointer;font-family:var(--md-code-font-family);font-size:.85em;margin:0 1ch;outline:none;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:0}.md-annotation .md-annotation__index{color:#fff;transition:z-index .25s}.md-annotation .md-annotation__index:-webkit-any(:focus,:hover){color:#fff}.md-annotation .md-annotation__index:-moz-any(:focus,:hover){color:#fff}.md-annotation .md-annotation__index:is(:focus,:hover){color:#fff}.md-annotation__index:after{background-color:var(--md-default-fg-color--lighter);border-radius:2ch;content:"";height:2.2ch;left:-.125em;margin:0 -.4ch;padding:0 .4ch;position:absolute;top:0;transition:color .25s,background-color .25s;width:calc(100% + 1.2ch);width:max(2.2ch,100% + 1.2ch);z-index:-1}@media not all and (prefers-reduced-motion){[data-md-visible]>.md-annotation__index:after{animation:pulse 2s infinite}}.md-tooltip--active+.md-annotation__index:after{animation:none;transition:color .25s,background-color .25s}code .md-annotation__index{font-family:var(--md-code-font-family);font-size:inherit}:-webkit-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:-moz-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:is(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index){color:var(--md-accent-bg-color)}:-webkit-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}:-moz-any(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}:is(.md-tooltip--active+.md-annotation__index,:hover>.md-annotation__index):after{background-color:var(--md-accent-fg-color)}.md-tooltip--active+.md-annotation__index{animation:none;transition:none;z-index:2}.md-annotation__index [data-md-annotation-id]{display:inline-block;line-height:90%}.md-annotation__index [data-md-annotation-id]:before{content:attr(data-md-annotation-id);display:inline-block;padding-bottom:.1em;transform:scale(1.15);transition:transform .4s cubic-bezier(.1,.7,.1,1);vertical-align:.065em}@media not print{.md-annotation__index [data-md-annotation-id]:before{content:"+"}:focus-within>.md-annotation__index [data-md-annotation-id]:before{transform:scale(1.25) rotate(45deg)}}[dir=ltr] .md-top{margin-left:50%}[dir=rtl] .md-top{margin-right:50%}.md-top{background-color:var(--md-default-bg-color);border-radius:1.6rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color--light);display:block;font-size:.7rem;outline:none;padding:.4rem .8rem;position:fixed;top:3.2rem;transform:translate(-50%);transition:color 125ms,background-color 125ms,transform 125ms cubic-bezier(.4,0,.2,1),opacity 125ms;z-index:2}@media print{.md-top{display:none}}[dir=rtl] .md-top{transform:translate(50%)}.md-top[hidden]{opacity:0;pointer-events:none;transform:translate(-50%,.2rem);transition-duration:0ms}[dir=rtl] .md-top[hidden]{transform:translate(50%,.2rem)}.md-top:-webkit-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:-moz-any(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top:is(:focus,:hover){background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.md-top svg{display:inline-block;vertical-align:-.5em}@keyframes hoverfix{0%{pointer-events:none}}:root{--md-version-icon:url('data:image/svg+xml;charset=utf-8,')}.md-version{flex-shrink:0;font-size:.8rem;height:2.4rem}[dir=ltr] .md-version__current{margin-left:1.4rem;margin-right:.4rem}[dir=rtl] .md-version__current{margin-left:.4rem;margin-right:1.4rem}.md-version__current{color:inherit;cursor:pointer;outline:none;position:relative;top:.05rem}[dir=ltr] .md-version__current:after{margin-left:.4rem}[dir=rtl] .md-version__current:after{margin-right:.4rem}.md-version__current:after{background-color:currentcolor;content:"";display:inline-block;height:.6rem;-webkit-mask-image:var(--md-version-icon);mask-image:var(--md-version-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.4rem}.md-version__list{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z2);color:var(--md-default-fg-color);list-style-type:none;margin:.2rem .8rem;max-height:0;opacity:0;overflow:auto;padding:0;position:absolute;scroll-snap-type:y mandatory;top:.15rem;transition:max-height 0ms .5s,opacity .25s .25s;z-index:3}.md-version:-webkit-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-webkit-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:-moz-any(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;-moz-transition:max-height 0ms,opacity .25s;transition:max-height 0ms,opacity .25s}.md-version:is(:focus-within,:hover) .md-version__list{max-height:10rem;opacity:1;transition:max-height 0ms,opacity .25s}@media (pointer:coarse){.md-version:hover .md-version__list{animation:hoverfix .25s forwards}.md-version:focus-within .md-version__list{animation:none}}.md-version__item{line-height:1.8rem}[dir=ltr] .md-version__link{padding-left:.6rem;padding-right:1.2rem}[dir=rtl] .md-version__link{padding-left:1.2rem;padding-right:.6rem}.md-version__link{cursor:pointer;display:block;outline:none;scroll-snap-align:start;transition:color .25s,background-color .25s;white-space:nowrap;width:100%}.md-version__link:-webkit-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:-moz-any(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:is(:focus,:hover){color:var(--md-accent-fg-color)}.md-version__link:focus{background-color:var(--md-default-fg-color--lightest)}:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .admonition,.md-typeset details{background-color:var(--md-admonition-bg-color);border:.05rem solid #448aff;border-radius:.2rem;box-shadow:var(--md-shadow-z1);color:var(--md-admonition-fg-color);display:flow-root;font-size:.64rem;margin:1.5625em 0;padding:0 .6rem;page-break-inside:avoid}@media print{.md-typeset .admonition,.md-typeset details{box-shadow:none}}.md-typeset .admonition>*,.md-typeset details>*{box-sizing:border-box}.md-typeset .admonition :-webkit-any(.admonition,details),.md-typeset details :-webkit-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset .admonition :-moz-any(.admonition,details),.md-typeset details :-moz-any(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset .admonition :is(.admonition,details),.md-typeset details :is(.admonition,details){margin-bottom:1em;margin-top:1em}.md-typeset .admonition .md-typeset__scrollwrap,.md-typeset details .md-typeset__scrollwrap{margin:1em -.6rem}.md-typeset .admonition .md-typeset__table,.md-typeset details .md-typeset__table{padding:0 .6rem}.md-typeset .admonition>.tabbed-set:only-child,.md-typeset details>.tabbed-set:only-child{margin-top:0}html .md-typeset .admonition>:last-child,html .md-typeset details>:last-child{margin-bottom:.6rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{padding-left:2rem;padding-right:.6rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{padding-left:.6rem;padding-right:2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-left-width:.2rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-right-width:.2rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset .admonition-title,[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset .admonition-title,[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset .admonition-title,.md-typeset summary{background-color:#448aff1a;border:none;font-weight:700;margin:0 -.6rem;padding-bottom:.4rem;padding-top:.4rem;position:relative}html .md-typeset .admonition-title:last-child,html .md-typeset summary:last-child{margin-bottom:0}[dir=ltr] .md-typeset .admonition-title:before,[dir=ltr] .md-typeset summary:before{left:.6rem}[dir=rtl] .md-typeset .admonition-title:before,[dir=rtl] .md-typeset summary:before{right:.6rem}.md-typeset .admonition-title:before,.md-typeset summary:before{background-color:#448aff;content:"";height:1rem;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;width:1rem}.md-typeset .admonition-title code,.md-typeset summary code{box-shadow:0 0 0 .05rem var(--md-default-fg-color--lightest)}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.note){border-color:#448aff}.md-typeset :-moz-any(.admonition,details):-moz-any(.note){border-color:#448aff}.md-typeset :is(.admonition,details):is(.note){border-color:#448aff}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary){background-color:#448aff1a}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary){background-color:#448aff1a}.md-typeset :is(.note)>:is(.admonition-title,summary){background-color:#448aff1a}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):before{background-color:#448aff;mask-image:var(--md-admonition-icon--note)}.md-typeset :is(.note)>:is(.admonition-title,summary):before{background-color:#448aff;-webkit-mask-image:var(--md-admonition-icon--note);mask-image:var(--md-admonition-icon--note)}.md-typeset :-webkit-any(.note)>:-webkit-any(.admonition-title,summary):after{color:#448aff}.md-typeset :-moz-any(.note)>:-moz-any(.admonition-title,summary):after{color:#448aff}.md-typeset :is(.note)>:is(.admonition-title,summary):after{color:#448aff}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-moz-any(.admonition,details):-moz-any(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :is(.admonition,details):is(.abstract,.summary,.tldr){border-color:#00b0ff}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary){background-color:#00b0ff1a}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary){background-color:#00b0ff1a}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary){background-color:#00b0ff1a}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):before{background-color:#00b0ff;mask-image:var(--md-admonition-icon--abstract)}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):before{background-color:#00b0ff;-webkit-mask-image:var(--md-admonition-icon--abstract);mask-image:var(--md-admonition-icon--abstract)}.md-typeset :-webkit-any(.abstract,.summary,.tldr)>:-webkit-any(.admonition-title,summary):after{color:#00b0ff}.md-typeset :-moz-any(.abstract,.summary,.tldr)>:-moz-any(.admonition-title,summary):after{color:#00b0ff}.md-typeset :is(.abstract,.summary,.tldr)>:is(.admonition-title,summary):after{color:#00b0ff}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.info,.todo){border-color:#00b8d4}.md-typeset :-moz-any(.admonition,details):-moz-any(.info,.todo){border-color:#00b8d4}.md-typeset :is(.admonition,details):is(.info,.todo){border-color:#00b8d4}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary){background-color:#00b8d41a}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary){background-color:#00b8d41a}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary){background-color:#00b8d41a}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):before{background-color:#00b8d4;mask-image:var(--md-admonition-icon--info)}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):before{background-color:#00b8d4;-webkit-mask-image:var(--md-admonition-icon--info);mask-image:var(--md-admonition-icon--info)}.md-typeset :-webkit-any(.info,.todo)>:-webkit-any(.admonition-title,summary):after{color:#00b8d4}.md-typeset :-moz-any(.info,.todo)>:-moz-any(.admonition-title,summary):after{color:#00b8d4}.md-typeset :is(.info,.todo)>:is(.admonition-title,summary):after{color:#00b8d4}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-moz-any(.admonition,details):-moz-any(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :is(.admonition,details):is(.tip,.hint,.important){border-color:#00bfa5}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary){background-color:#00bfa51a}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary){background-color:#00bfa51a}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary){background-color:#00bfa51a}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):before{background-color:#00bfa5;mask-image:var(--md-admonition-icon--tip)}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):before{background-color:#00bfa5;-webkit-mask-image:var(--md-admonition-icon--tip);mask-image:var(--md-admonition-icon--tip)}.md-typeset :-webkit-any(.tip,.hint,.important)>:-webkit-any(.admonition-title,summary):after{color:#00bfa5}.md-typeset :-moz-any(.tip,.hint,.important)>:-moz-any(.admonition-title,summary):after{color:#00bfa5}.md-typeset :is(.tip,.hint,.important)>:is(.admonition-title,summary):after{color:#00bfa5}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.success,.check,.done){border-color:#00c853}.md-typeset :-moz-any(.admonition,details):-moz-any(.success,.check,.done){border-color:#00c853}.md-typeset :is(.admonition,details):is(.success,.check,.done){border-color:#00c853}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary){background-color:#00c8531a}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary){background-color:#00c8531a}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary){background-color:#00c8531a}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):before{background-color:#00c853;mask-image:var(--md-admonition-icon--success)}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):before{background-color:#00c853;-webkit-mask-image:var(--md-admonition-icon--success);mask-image:var(--md-admonition-icon--success)}.md-typeset :-webkit-any(.success,.check,.done)>:-webkit-any(.admonition-title,summary):after{color:#00c853}.md-typeset :-moz-any(.success,.check,.done)>:-moz-any(.admonition-title,summary):after{color:#00c853}.md-typeset :is(.success,.check,.done)>:is(.admonition-title,summary):after{color:#00c853}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :-moz-any(.admonition,details):-moz-any(.question,.help,.faq){border-color:#64dd17}.md-typeset :is(.admonition,details):is(.question,.help,.faq){border-color:#64dd17}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary){background-color:#64dd171a}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary){background-color:#64dd171a}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary){background-color:#64dd171a}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):before{background-color:#64dd17;mask-image:var(--md-admonition-icon--question)}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):before{background-color:#64dd17;-webkit-mask-image:var(--md-admonition-icon--question);mask-image:var(--md-admonition-icon--question)}.md-typeset :-webkit-any(.question,.help,.faq)>:-webkit-any(.admonition-title,summary):after{color:#64dd17}.md-typeset :-moz-any(.question,.help,.faq)>:-moz-any(.admonition-title,summary):after{color:#64dd17}.md-typeset :is(.question,.help,.faq)>:is(.admonition-title,summary):after{color:#64dd17}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-moz-any(.admonition,details):-moz-any(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :is(.admonition,details):is(.warning,.caution,.attention){border-color:#ff9100}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary){background-color:#ff91001a}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary){background-color:#ff91001a}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary){background-color:#ff91001a}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):before{background-color:#ff9100;mask-image:var(--md-admonition-icon--warning)}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):before{background-color:#ff9100;-webkit-mask-image:var(--md-admonition-icon--warning);mask-image:var(--md-admonition-icon--warning)}.md-typeset :-webkit-any(.warning,.caution,.attention)>:-webkit-any(.admonition-title,summary):after{color:#ff9100}.md-typeset :-moz-any(.warning,.caution,.attention)>:-moz-any(.admonition-title,summary):after{color:#ff9100}.md-typeset :is(.warning,.caution,.attention)>:is(.admonition-title,summary):after{color:#ff9100}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-moz-any(.admonition,details):-moz-any(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :is(.admonition,details):is(.failure,.fail,.missing){border-color:#ff5252}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary){background-color:#ff52521a}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary){background-color:#ff52521a}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary){background-color:#ff52521a}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):before{background-color:#ff5252;mask-image:var(--md-admonition-icon--failure)}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):before{background-color:#ff5252;-webkit-mask-image:var(--md-admonition-icon--failure);mask-image:var(--md-admonition-icon--failure)}.md-typeset :-webkit-any(.failure,.fail,.missing)>:-webkit-any(.admonition-title,summary):after{color:#ff5252}.md-typeset :-moz-any(.failure,.fail,.missing)>:-moz-any(.admonition-title,summary):after{color:#ff5252}.md-typeset :is(.failure,.fail,.missing)>:is(.admonition-title,summary):after{color:#ff5252}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.danger,.error){border-color:#ff1744}.md-typeset :-moz-any(.admonition,details):-moz-any(.danger,.error){border-color:#ff1744}.md-typeset :is(.admonition,details):is(.danger,.error){border-color:#ff1744}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary){background-color:#ff17441a}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary){background-color:#ff17441a}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary){background-color:#ff17441a}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):before{background-color:#ff1744;mask-image:var(--md-admonition-icon--danger)}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):before{background-color:#ff1744;-webkit-mask-image:var(--md-admonition-icon--danger);mask-image:var(--md-admonition-icon--danger)}.md-typeset :-webkit-any(.danger,.error)>:-webkit-any(.admonition-title,summary):after{color:#ff1744}.md-typeset :-moz-any(.danger,.error)>:-moz-any(.admonition-title,summary):after{color:#ff1744}.md-typeset :is(.danger,.error)>:is(.admonition-title,summary):after{color:#ff1744}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.bug){border-color:#f50057}.md-typeset :-moz-any(.admonition,details):-moz-any(.bug){border-color:#f50057}.md-typeset :is(.admonition,details):is(.bug){border-color:#f50057}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary){background-color:#f500571a}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary){background-color:#f500571a}.md-typeset :is(.bug)>:is(.admonition-title,summary){background-color:#f500571a}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):before{background-color:#f50057;mask-image:var(--md-admonition-icon--bug)}.md-typeset :is(.bug)>:is(.admonition-title,summary):before{background-color:#f50057;-webkit-mask-image:var(--md-admonition-icon--bug);mask-image:var(--md-admonition-icon--bug)}.md-typeset :-webkit-any(.bug)>:-webkit-any(.admonition-title,summary):after{color:#f50057}.md-typeset :-moz-any(.bug)>:-moz-any(.admonition-title,summary):after{color:#f50057}.md-typeset :is(.bug)>:is(.admonition-title,summary):after{color:#f50057}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.example){border-color:#7c4dff}.md-typeset :-moz-any(.admonition,details):-moz-any(.example){border-color:#7c4dff}.md-typeset :is(.admonition,details):is(.example){border-color:#7c4dff}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary){background-color:#7c4dff1a}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary){background-color:#7c4dff1a}.md-typeset :is(.example)>:is(.admonition-title,summary){background-color:#7c4dff1a}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):before{background-color:#7c4dff;mask-image:var(--md-admonition-icon--example)}.md-typeset :is(.example)>:is(.admonition-title,summary):before{background-color:#7c4dff;-webkit-mask-image:var(--md-admonition-icon--example);mask-image:var(--md-admonition-icon--example)}.md-typeset :-webkit-any(.example)>:-webkit-any(.admonition-title,summary):after{color:#7c4dff}.md-typeset :-moz-any(.example)>:-moz-any(.admonition-title,summary):after{color:#7c4dff}.md-typeset :is(.example)>:is(.admonition-title,summary):after{color:#7c4dff}.md-typeset :-webkit-any(.admonition,details):-webkit-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :-moz-any(.admonition,details):-moz-any(.quote,.cite){border-color:#9e9e9e}.md-typeset :is(.admonition,details):is(.quote,.cite){border-color:#9e9e9e}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary){background-color:#9e9e9e1a}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary){background-color:#9e9e9e1a}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary){background-color:#9e9e9e1a}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):before{background-color:#9e9e9e;mask-image:var(--md-admonition-icon--quote)}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):before{background-color:#9e9e9e;-webkit-mask-image:var(--md-admonition-icon--quote);mask-image:var(--md-admonition-icon--quote)}.md-typeset :-webkit-any(.quote,.cite)>:-webkit-any(.admonition-title,summary):after{color:#9e9e9e}.md-typeset :-moz-any(.quote,.cite)>:-moz-any(.admonition-title,summary):after{color:#9e9e9e}.md-typeset :is(.quote,.cite)>:is(.admonition-title,summary):after{color:#9e9e9e}:root{--md-footnotes-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .footnote{color:var(--md-default-fg-color--light);font-size:.64rem}[dir=ltr] .md-typeset .footnote>ol{margin-left:0}[dir=rtl] .md-typeset .footnote>ol{margin-right:0}.md-typeset .footnote>ol>li{transition:color 125ms}.md-typeset .footnote>ol>li:target{color:var(--md-default-fg-color)}.md-typeset .footnote>ol>li:focus-within .footnote-backref{opacity:1;transform:translateX(0);transition:none}.md-typeset .footnote>ol>li:-webkit-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:-moz-any(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li:is(:hover,:target) .footnote-backref{opacity:1;transform:translateX(0)}.md-typeset .footnote>ol>li>:first-child{margin-top:0}.md-typeset .footnote-ref{font-size:.75em;font-weight:700}html .md-typeset .footnote-ref{outline-offset:.1rem}.md-typeset [id^="fnref:"]:target>.footnote-ref{outline:auto}.md-typeset .footnote-backref{color:var(--md-typeset-a-color);display:inline-block;font-size:0;opacity:0;transform:translateX(.25rem);transition:color .25s,transform .25s .25s,opacity 125ms .25s;vertical-align:text-bottom}@media print{.md-typeset .footnote-backref{color:var(--md-typeset-a-color);opacity:1;transform:translateX(0)}}[dir=rtl] .md-typeset .footnote-backref{transform:translateX(-.25rem)}.md-typeset .footnote-backref:hover{color:var(--md-accent-fg-color)}.md-typeset .footnote-backref:before{background-color:currentcolor;content:"";display:inline-block;height:.8rem;-webkit-mask-image:var(--md-footnotes-icon);mask-image:var(--md-footnotes-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;width:.8rem}[dir=rtl] .md-typeset .footnote-backref:before svg{transform:scaleX(-1)}[dir=ltr] .md-typeset .headerlink{margin-left:.5rem}[dir=rtl] .md-typeset .headerlink{margin-right:.5rem}.md-typeset .headerlink{color:var(--md-default-fg-color--lighter);display:inline-block;opacity:0;transition:color .25s,opacity 125ms}@media print{.md-typeset .headerlink{display:none}}.md-typeset .headerlink:focus,.md-typeset :-webkit-any(:hover,:target)>.headerlink{opacity:1;-webkit-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :-moz-any(:hover,:target)>.headerlink{opacity:1;-moz-transition:color .25s,opacity 125ms;transition:color .25s,opacity 125ms}.md-typeset .headerlink:focus,.md-typeset :is(:hover,:target)>.headerlink{opacity:1;transition:color .25s,opacity 125ms}.md-typeset .headerlink:-webkit-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:-moz-any(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset .headerlink:is(:focus,:hover),.md-typeset :target>.headerlink{color:var(--md-accent-fg-color)}.md-typeset :target{--md-scroll-margin:3.6rem;--md-scroll-offset:0rem;scroll-margin-top:calc(var(--md-scroll-margin) - var(--md-scroll-offset))}@media screen and (min-width:76.25em){.md-header--lifted~.md-container .md-typeset :target{--md-scroll-margin:6rem}}.md-typeset :-webkit-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :-moz-any(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset :is(h1,h2,h3):target{--md-scroll-offset:0.2rem}.md-typeset h4:target{--md-scroll-offset:0.15rem}.md-typeset div.arithmatex{overflow:auto}@media screen and (max-width:44.9375em){.md-typeset div.arithmatex{margin:0 -.8rem}}.md-typeset div.arithmatex>*{margin-left:auto!important;margin-right:auto!important;padding:0 .8rem;touch-action:auto;width:-webkit-min-content;width:-moz-min-content;width:min-content}.md-typeset div.arithmatex>* mjx-container{margin:0!important}.md-typeset :-webkit-any(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset :-moz-any(del,ins,.comment).critic{box-decoration-break:clone}.md-typeset :is(del,ins,.comment).critic{-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:var(--md-typeset-del-color)}.md-typeset ins.critic{background-color:var(--md-typeset-ins-color)}.md-typeset .critic.comment{color:var(--md-code-hl-comment-color)}.md-typeset .critic.comment:before{content:"/* "}.md-typeset .critic.comment:after{content:" */"}.md-typeset .critic.block{box-shadow:none;display:block;margin:1em 0;overflow:auto;padding-left:.8rem;padding-right:.8rem}.md-typeset .critic.block>:first-child{margin-top:.5em}.md-typeset .critic.block>:last-child{margin-bottom:.5em}:root{--md-details-icon:url('data:image/svg+xml;charset=utf-8,')}.md-typeset details{display:flow-root;overflow:visible;padding-top:0}.md-typeset details[open]>summary:after{transform:rotate(90deg)}.md-typeset details:not([open]){box-shadow:none;padding-bottom:0}.md-typeset details:not([open])>summary{border-radius:.1rem}[dir=ltr] .md-typeset summary{padding-right:1.8rem}[dir=rtl] .md-typeset summary{padding-left:1.8rem}[dir=ltr] .md-typeset summary{border-top-left-radius:.1rem}[dir=ltr] .md-typeset summary,[dir=rtl] .md-typeset summary{border-top-right-radius:.1rem}[dir=rtl] .md-typeset summary{border-top-left-radius:.1rem}.md-typeset summary{cursor:pointer;display:block;min-height:1rem}.md-typeset summary.focus-visible{outline-color:var(--md-accent-fg-color);outline-offset:.2rem}.md-typeset summary:not(.focus-visible){-webkit-tap-highlight-color:transparent;outline:none}[dir=ltr] .md-typeset summary:after{right:.4rem}[dir=rtl] .md-typeset summary:after{left:.4rem}.md-typeset summary:after{background-color:currentcolor;content:"";height:1rem;-webkit-mask-image:var(--md-details-icon);mask-image:var(--md-details-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.625em;transform:rotate(0deg);transition:transform .25s;width:1rem}[dir=rtl] .md-typeset summary:after{transform:rotate(180deg)}.md-typeset summary::marker{display:none}.md-typeset summary::-webkit-details-marker{display:none}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :is(.emojione,.twemoji,.gemoji){display:inline-flex;height:1.125em;vertical-align:text-top}.md-typeset :-webkit-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :-moz-any(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.md-typeset :is(.emojione,.twemoji,.gemoji) svg{fill:currentcolor;max-height:100%;width:1.125em}.highlight :-webkit-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :-moz-any(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight :is(.o,.ow){color:var(--md-code-hl-operator-color)}.highlight .p{color:var(--md-code-hl-punctuation-color)}.highlight :-webkit-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-moz-any(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :is(.cpf,.l,.s,.sb,.sc,.s2,.si,.s1,.ss){color:var(--md-code-hl-string-color)}.highlight :-webkit-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-moz-any(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :is(.cp,.se,.sh,.sr,.sx){color:var(--md-code-hl-special-color)}.highlight :-webkit-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-moz-any(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :is(.m,.mb,.mf,.mh,.mi,.il,.mo){color:var(--md-code-hl-number-color)}.highlight :-webkit-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :is(.k,.kd,.kn,.kp,.kr,.kt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-moz-any(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :is(.kc,.n){color:var(--md-code-hl-name-color)}.highlight :-webkit-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-moz-any(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :is(.no,.nb,.bp){color:var(--md-code-hl-constant-color)}.highlight :-webkit-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-moz-any(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :is(.nc,.ne,.nf,.nn){color:var(--md-code-hl-function-color)}.highlight :-webkit-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-moz-any(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :is(.nd,.ni,.nl,.nt){color:var(--md-code-hl-keyword-color)}.highlight :-webkit-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-moz-any(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :is(.c,.cm,.c1,.ch,.cs,.sd){color:var(--md-code-hl-comment-color)}.highlight :-webkit-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-moz-any(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :is(.na,.nv,.vc,.vg,.vi){color:var(--md-code-hl-variable-color)}.highlight :-webkit-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-moz-any(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :is(.ge,.gr,.gh,.go,.gp,.gs,.gu,.gt){color:var(--md-code-hl-generic-color)}.highlight :-webkit-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :-moz-any(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight :is(.gd,.gi){border-radius:.1rem;margin:0 -.125em;padding:0 .125em}.highlight .gd{background-color:var(--md-typeset-del-color)}.highlight .gi{background-color:var(--md-typeset-ins-color)}.highlight .hll{background-color:var(--md-code-hl-color);display:block;margin:0 -1.1764705882em;padding:0 1.1764705882em}.highlight span.filename{background-color:var(--md-code-bg-color);border-bottom:.05rem solid var(--md-default-fg-color--lightest);border-top-left-radius:.1rem;border-top-right-radius:.1rem;display:flow-root;font-size:.85em;font-weight:700;margin-top:1em;padding:.6617647059em 1.1764705882em;position:relative}.highlight span.filename+pre{margin-top:0}.highlight span.filename+pre>code{border-top-left-radius:0;border-top-right-radius:0}.highlight [data-linenos]:before{background-color:var(--md-code-bg-color);box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;color:var(--md-default-fg-color--light);content:attr(data-linenos);float:left;left:-1.1764705882em;margin-left:-1.1764705882em;margin-right:1.1764705882em;padding-left:1.1764705882em;position:-webkit-sticky;position:sticky;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:3}.highlight code a[id]{position:absolute;visibility:hidden}.highlight code[data-md-copying] .hll{display:contents}.highlight code[data-md-copying] .md-annotation{display:none}.highlighttable{display:flow-root}.highlighttable :-webkit-any(tbody,td){display:block;padding:0}.highlighttable :-moz-any(tbody,td){display:block;padding:0}.highlighttable :is(tbody,td){display:block;padding:0}.highlighttable tr{display:flex}.highlighttable pre{margin:0}.highlighttable th.filename{flex-grow:1;padding:0;text-align:left}.highlighttable th.filename span.filename{margin-top:0}.highlighttable .linenos{background-color:var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-top-left-radius:.1rem;font-size:.85em;padding:.7720588235em 0 .7720588235em 1.1764705882em;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlighttable .linenodiv{box-shadow:-.05rem 0 var(--md-default-fg-color--lightest) inset;padding-right:.5882352941em}.highlighttable .linenodiv pre{color:var(--md-default-fg-color--light);text-align:right}.highlighttable .code{flex:1;min-width:0}.linenodiv a{color:inherit}.md-typeset .highlighttable{direction:ltr;margin:1em 0}.md-typeset .highlighttable>tbody>tr>.code>div>pre>code{border-bottom-left-radius:0;border-top-left-radius:0}.md-typeset .highlight+.result{border:.05rem solid var(--md-code-bg-color);border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top-width:.1rem;margin-top:-1.125em;overflow:visible;padding:0 1em}.md-typeset .highlight+.result:after{clear:both;content:"";display:block}@media screen and (max-width:44.9375em){.md-content__inner>.highlight{margin:1em -.8rem}.md-content__inner>.highlight>.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.code>div>pre>code,.md-content__inner>.highlight>.highlighttable>tbody>tr>.filename span.filename,.md-content__inner>.highlight>.highlighttable>tbody>tr>.linenos,.md-content__inner>.highlight>pre>code{border-radius:0}.md-content__inner>.highlight+.result{border-left-width:0;border-radius:0;border-right-width:0;margin-left:-.8rem;margin-right:-.8rem}}.md-typeset .keys kbd:-webkit-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:-moz-any(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys kbd:is(:before,:after){-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;color:inherit;margin:0;position:relative}.md-typeset .keys span{color:var(--md-default-fg-color--light);padding:0 .2em}.md-typeset .keys .key-alt:before,.md-typeset .keys .key-left-alt:before,.md-typeset .keys .key-right-alt:before{content:"⎇";padding-right:.4em}.md-typeset .keys .key-command:before,.md-typeset .keys .key-left-command:before,.md-typeset .keys .key-right-command:before{content:"⌘";padding-right:.4em}.md-typeset .keys .key-control:before,.md-typeset .keys .key-left-control:before,.md-typeset .keys .key-right-control:before{content:"⌃";padding-right:.4em}.md-typeset .keys .key-left-meta:before,.md-typeset .keys .key-meta:before,.md-typeset .keys .key-right-meta:before{content:"◆";padding-right:.4em}.md-typeset .keys .key-left-option:before,.md-typeset .keys .key-option:before,.md-typeset .keys .key-right-option:before{content:"⌥";padding-right:.4em}.md-typeset .keys .key-left-shift:before,.md-typeset .keys .key-right-shift:before,.md-typeset .keys .key-shift:before{content:"⇧";padding-right:.4em}.md-typeset .keys .key-left-super:before,.md-typeset .keys .key-right-super:before,.md-typeset .keys .key-super:before{content:"❖";padding-right:.4em}.md-typeset .keys .key-left-windows:before,.md-typeset .keys .key-right-windows:before,.md-typeset .keys .key-windows:before{content:"⊞";padding-right:.4em}.md-typeset .keys .key-arrow-down:before{content:"↓";padding-right:.4em}.md-typeset .keys .key-arrow-left:before{content:"←";padding-right:.4em}.md-typeset .keys .key-arrow-right:before{content:"→";padding-right:.4em}.md-typeset .keys .key-arrow-up:before{content:"↑";padding-right:.4em}.md-typeset .keys .key-backspace:before{content:"⌫";padding-right:.4em}.md-typeset .keys .key-backtab:before{content:"⇤";padding-right:.4em}.md-typeset .keys .key-caps-lock:before{content:"⇪";padding-right:.4em}.md-typeset .keys .key-clear:before{content:"⌧";padding-right:.4em}.md-typeset .keys .key-context-menu:before{content:"☰";padding-right:.4em}.md-typeset .keys .key-delete:before{content:"⌦";padding-right:.4em}.md-typeset .keys .key-eject:before{content:"⏏";padding-right:.4em}.md-typeset .keys .key-end:before{content:"⤓";padding-right:.4em}.md-typeset .keys .key-escape:before{content:"⎋";padding-right:.4em}.md-typeset .keys .key-home:before{content:"⤒";padding-right:.4em}.md-typeset .keys .key-insert:before{content:"⎀";padding-right:.4em}.md-typeset .keys .key-page-down:before{content:"⇟";padding-right:.4em}.md-typeset .keys .key-page-up:before{content:"⇞";padding-right:.4em}.md-typeset .keys .key-print-screen:before{content:"⎙";padding-right:.4em}.md-typeset .keys .key-tab:after{content:"⇥";padding-left:.4em}.md-typeset .keys .key-num-enter:after{content:"⌤";padding-left:.4em}.md-typeset .keys .key-enter:after{content:"⏎";padding-left:.4em}:root{--md-tabbed-icon--prev:url('data:image/svg+xml;charset=utf-8,');--md-tabbed-icon--next:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .tabbed-set{border-radius:.1rem;display:flex;flex-flow:column wrap;margin:1em 0;position:relative}.md-typeset .tabbed-set>input{height:0;opacity:0;position:absolute;width:0}.md-typeset .tabbed-set>input:target{--md-scroll-offset:0.625em}.md-typeset .tabbed-labels{-ms-overflow-style:none;box-shadow:0 -.05rem var(--md-default-fg-color--lightest) inset;display:flex;max-width:100%;overflow:auto;scrollbar-width:none}@media print{.md-typeset .tabbed-labels{display:contents}}@media screen{.js .md-typeset .tabbed-labels{position:relative}.js .md-typeset .tabbed-labels:before{background:var(--md-accent-fg-color);bottom:0;content:"";display:block;height:2px;left:0;position:absolute;transform:translateX(var(--md-indicator-x));transition:width 225ms,transform .25s;transition-timing-function:cubic-bezier(.4,0,.2,1);width:var(--md-indicator-width)}}.md-typeset .tabbed-labels::-webkit-scrollbar{display:none}.md-typeset .tabbed-labels>label{border-bottom:.1rem solid #0000;border-radius:.1rem .1rem 0 0;color:var(--md-default-fg-color--light);cursor:pointer;flex-shrink:0;font-size:.64rem;font-weight:700;padding:.78125em 1.25em .625em;scroll-margin-inline-start:1rem;transition:background-color .25s,color .25s;white-space:nowrap;width:auto}@media print{.md-typeset .tabbed-labels>label:first-child{order:1}.md-typeset .tabbed-labels>label:nth-child(2){order:2}.md-typeset .tabbed-labels>label:nth-child(3){order:3}.md-typeset .tabbed-labels>label:nth-child(4){order:4}.md-typeset .tabbed-labels>label:nth-child(5){order:5}.md-typeset .tabbed-labels>label:nth-child(6){order:6}.md-typeset .tabbed-labels>label:nth-child(7){order:7}.md-typeset .tabbed-labels>label:nth-child(8){order:8}.md-typeset .tabbed-labels>label:nth-child(9){order:9}.md-typeset .tabbed-labels>label:nth-child(10){order:10}.md-typeset .tabbed-labels>label:nth-child(11){order:11}.md-typeset .tabbed-labels>label:nth-child(12){order:12}.md-typeset .tabbed-labels>label:nth-child(13){order:13}.md-typeset .tabbed-labels>label:nth-child(14){order:14}.md-typeset .tabbed-labels>label:nth-child(15){order:15}.md-typeset .tabbed-labels>label:nth-child(16){order:16}.md-typeset .tabbed-labels>label:nth-child(17){order:17}.md-typeset .tabbed-labels>label:nth-child(18){order:18}.md-typeset .tabbed-labels>label:nth-child(19){order:19}.md-typeset .tabbed-labels>label:nth-child(20){order:20}}.md-typeset .tabbed-labels>label:hover{color:var(--md-accent-fg-color)}.md-typeset .tabbed-content{width:100%}@media print{.md-typeset .tabbed-content{display:contents}}.md-typeset .tabbed-block{display:none}@media print{.md-typeset .tabbed-block{display:block}.md-typeset .tabbed-block:first-child{order:1}.md-typeset .tabbed-block:nth-child(2){order:2}.md-typeset .tabbed-block:nth-child(3){order:3}.md-typeset .tabbed-block:nth-child(4){order:4}.md-typeset .tabbed-block:nth-child(5){order:5}.md-typeset .tabbed-block:nth-child(6){order:6}.md-typeset .tabbed-block:nth-child(7){order:7}.md-typeset .tabbed-block:nth-child(8){order:8}.md-typeset .tabbed-block:nth-child(9){order:9}.md-typeset .tabbed-block:nth-child(10){order:10}.md-typeset .tabbed-block:nth-child(11){order:11}.md-typeset .tabbed-block:nth-child(12){order:12}.md-typeset .tabbed-block:nth-child(13){order:13}.md-typeset .tabbed-block:nth-child(14){order:14}.md-typeset .tabbed-block:nth-child(15){order:15}.md-typeset .tabbed-block:nth-child(16){order:16}.md-typeset .tabbed-block:nth-child(17){order:17}.md-typeset .tabbed-block:nth-child(18){order:18}.md-typeset .tabbed-block:nth-child(19){order:19}.md-typeset .tabbed-block:nth-child(20){order:20}}.md-typeset .tabbed-block>.highlight:first-child>pre,.md-typeset .tabbed-block>pre:first-child{margin:0}.md-typeset .tabbed-block>.highlight:first-child>pre>code,.md-typeset .tabbed-block>pre:first-child>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child>.filename{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable{margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.filename span.filename,.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.linenos{border-top-left-radius:0;border-top-right-radius:0;margin:0}.md-typeset .tabbed-block>.highlight:first-child>.highlighttable>tbody>tr>.code>div>pre>code{border-top-left-radius:0;border-top-right-radius:0}.md-typeset .tabbed-block>.highlight:first-child+.result{margin-top:-.125em}.md-typeset .tabbed-block>.tabbed-set{margin:0}.md-typeset .tabbed-button{align-self:center;border-radius:100%;color:var(--md-default-fg-color--light);cursor:pointer;display:block;height:.9rem;margin-top:.1rem;pointer-events:auto;transition:background-color .25s;width:.9rem}.md-typeset .tabbed-button:hover{background-color:var(--md-accent-fg-color--transparent);color:var(--md-accent-fg-color)}.md-typeset .tabbed-button:after{background-color:currentcolor;content:"";display:block;height:100%;-webkit-mask-image:var(--md-tabbed-icon--prev);mask-image:var(--md-tabbed-icon--prev);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background-color .25s,transform .25s;width:100%}.md-typeset .tabbed-control{background:linear-gradient(to right,var(--md-default-bg-color) 60%,#0000);display:flex;height:1.9rem;justify-content:start;pointer-events:none;position:absolute;transition:opacity 125ms;width:1.2rem}[dir=rtl] .md-typeset .tabbed-control{transform:rotate(180deg)}.md-typeset .tabbed-control[hidden]{opacity:0}.md-typeset .tabbed-control--next{background:linear-gradient(to left,var(--md-default-bg-color) 60%,#0000);justify-content:end;right:0}.md-typeset .tabbed-control--next .tabbed-button:after{-webkit-mask-image:var(--md-tabbed-icon--next);mask-image:var(--md-tabbed-icon--next)}@media screen and (max-width:44.9375em){[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels{margin:0 -.8rem;max-width:100vw;scroll-padding-inline-start:.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels:after{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels:after{content:""}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-left:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{margin-right:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-left:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{padding-right:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--prev{width:2rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-right:-.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{margin-left:-.8rem}[dir=ltr] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-right:.8rem}[dir=rtl] .md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{padding-left:.8rem}.md-content__inner>.tabbed-set .tabbed-labels~.tabbed-control--next{width:2rem}}@media screen{.md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){color:var(--md-accent-fg-color)}.md-typeset .no-js .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.md-typeset .no-js .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.md-typeset .no-js .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.md-typeset .no-js .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.md-typeset .no-js .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.md-typeset .no-js .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.md-typeset .no-js .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.md-typeset .no-js .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.md-typeset .no-js .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.md-typeset .no-js .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.md-typeset .no-js .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.md-typeset .no-js .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.md-typeset .no-js .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.md-typeset .no-js .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.md-typeset .no-js .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.md-typeset .no-js .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.md-typeset .no-js .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.md-typeset .no-js .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.md-typeset .no-js .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.md-typeset .no-js .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9),.no-js .md-typeset .tabbed-set>input:first-child:checked~.tabbed-labels>:first-child,.no-js .md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-labels>:nth-child(10),.no-js .md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-labels>:nth-child(11),.no-js .md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-labels>:nth-child(12),.no-js .md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-labels>:nth-child(13),.no-js .md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-labels>:nth-child(14),.no-js .md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-labels>:nth-child(15),.no-js .md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-labels>:nth-child(16),.no-js .md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-labels>:nth-child(17),.no-js .md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-labels>:nth-child(18),.no-js .md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-labels>:nth-child(19),.no-js .md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-labels>:nth-child(2),.no-js .md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-labels>:nth-child(20),.no-js .md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-labels>:nth-child(3),.no-js .md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-labels>:nth-child(4),.no-js .md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-labels>:nth-child(5),.no-js .md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-labels>:nth-child(6),.no-js .md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-labels>:nth-child(7),.no-js .md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-labels>:nth-child(8),.no-js .md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-labels>:nth-child(9){border-color:var(--md-accent-fg-color)}}.md-typeset .tabbed-set>input:first-child.focus-visible~.tabbed-labels>:first-child,.md-typeset .tabbed-set>input:nth-child(10).focus-visible~.tabbed-labels>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11).focus-visible~.tabbed-labels>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12).focus-visible~.tabbed-labels>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13).focus-visible~.tabbed-labels>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14).focus-visible~.tabbed-labels>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15).focus-visible~.tabbed-labels>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16).focus-visible~.tabbed-labels>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17).focus-visible~.tabbed-labels>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18).focus-visible~.tabbed-labels>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19).focus-visible~.tabbed-labels>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2).focus-visible~.tabbed-labels>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20).focus-visible~.tabbed-labels>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3).focus-visible~.tabbed-labels>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4).focus-visible~.tabbed-labels>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5).focus-visible~.tabbed-labels>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6).focus-visible~.tabbed-labels>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7).focus-visible~.tabbed-labels>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8).focus-visible~.tabbed-labels>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9).focus-visible~.tabbed-labels>:nth-child(9){background-color:var(--md-accent-fg-color--transparent)}.md-typeset .tabbed-set>input:first-child:checked~.tabbed-content>:first-child,.md-typeset .tabbed-set>input:nth-child(10):checked~.tabbed-content>:nth-child(10),.md-typeset .tabbed-set>input:nth-child(11):checked~.tabbed-content>:nth-child(11),.md-typeset .tabbed-set>input:nth-child(12):checked~.tabbed-content>:nth-child(12),.md-typeset .tabbed-set>input:nth-child(13):checked~.tabbed-content>:nth-child(13),.md-typeset .tabbed-set>input:nth-child(14):checked~.tabbed-content>:nth-child(14),.md-typeset .tabbed-set>input:nth-child(15):checked~.tabbed-content>:nth-child(15),.md-typeset .tabbed-set>input:nth-child(16):checked~.tabbed-content>:nth-child(16),.md-typeset .tabbed-set>input:nth-child(17):checked~.tabbed-content>:nth-child(17),.md-typeset .tabbed-set>input:nth-child(18):checked~.tabbed-content>:nth-child(18),.md-typeset .tabbed-set>input:nth-child(19):checked~.tabbed-content>:nth-child(19),.md-typeset .tabbed-set>input:nth-child(2):checked~.tabbed-content>:nth-child(2),.md-typeset .tabbed-set>input:nth-child(20):checked~.tabbed-content>:nth-child(20),.md-typeset .tabbed-set>input:nth-child(3):checked~.tabbed-content>:nth-child(3),.md-typeset .tabbed-set>input:nth-child(4):checked~.tabbed-content>:nth-child(4),.md-typeset .tabbed-set>input:nth-child(5):checked~.tabbed-content>:nth-child(5),.md-typeset .tabbed-set>input:nth-child(6):checked~.tabbed-content>:nth-child(6),.md-typeset .tabbed-set>input:nth-child(7):checked~.tabbed-content>:nth-child(7),.md-typeset .tabbed-set>input:nth-child(8):checked~.tabbed-content>:nth-child(8),.md-typeset .tabbed-set>input:nth-child(9):checked~.tabbed-content>:nth-child(9){display:block}:root{--md-tasklist-icon:url('data:image/svg+xml;charset=utf-8,');--md-tasklist-icon--checked:url('data:image/svg+xml;charset=utf-8,')}.md-typeset .task-list-item{list-style-type:none;position:relative}[dir=ltr] .md-typeset .task-list-item [type=checkbox]{left:-2em}[dir=rtl] .md-typeset .task-list-item [type=checkbox]{right:-2em}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}[dir=ltr] .md-typeset .task-list-indicator:before{left:-1.5em}[dir=rtl] .md-typeset .task-list-indicator:before{right:-1.5em}.md-typeset .task-list-indicator:before{background-color:var(--md-default-fg-color--lightest);content:"";height:1.25em;-webkit-mask-image:var(--md-tasklist-icon);mask-image:var(--md-tasklist-icon);-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;position:absolute;top:.15em;width:1.25em}.md-typeset [type=checkbox]:checked+.task-list-indicator:before{background-color:#00e676;-webkit-mask-image:var(--md-tasklist-icon--checked);mask-image:var(--md-tasklist-icon--checked)}:root>*{--md-mermaid-font-family:var(--md-text-font-family),sans-serif;--md-mermaid-edge-color:var(--md-code-fg-color);--md-mermaid-node-bg-color:var(--md-accent-fg-color--transparent);--md-mermaid-node-fg-color:var(--md-accent-fg-color);--md-mermaid-label-bg-color:var(--md-default-bg-color);--md-mermaid-label-fg-color:var(--md-code-fg-color)}.mermaid{line-height:normal;margin:1em 0}@media screen and (min-width:45em){[dir=ltr] .md-typeset .inline{float:left}[dir=rtl] .md-typeset .inline{float:right}[dir=ltr] .md-typeset .inline{margin-right:.8rem}[dir=rtl] .md-typeset .inline{margin-left:.8rem}.md-typeset .inline{margin-bottom:.8rem;margin-top:0;width:11.7rem}[dir=ltr] .md-typeset .inline.end{float:right}[dir=rtl] .md-typeset .inline.end{float:left}[dir=ltr] .md-typeset .inline.end{margin-left:.8rem;margin-right:0}[dir=rtl] .md-typeset .inline.end{margin-left:0;margin-right:.8rem}} \ No newline at end of file diff --git a/assets/stylesheets/main.975780f9.min.css.map b/assets/stylesheets/main.975780f9.min.css.map new file mode 100644 index 000000000..5e13ffb9c --- /dev/null +++ b/assets/stylesheets/main.975780f9.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/assets/stylesheets/main/extensions/pymdownx/_keys.scss","../../../src/assets/stylesheets/main.scss","src/assets/stylesheets/main/_resets.scss","src/assets/stylesheets/main/_colors.scss","src/assets/stylesheets/main/_icons.scss","src/assets/stylesheets/main/_typeset.scss","src/assets/stylesheets/utilities/_break.scss","src/assets/stylesheets/main/layout/_banner.scss","src/assets/stylesheets/main/layout/_base.scss","src/assets/stylesheets/main/layout/_clipboard.scss","src/assets/stylesheets/main/layout/_consent.scss","src/assets/stylesheets/main/layout/_content.scss","src/assets/stylesheets/main/layout/_dialog.scss","src/assets/stylesheets/main/layout/_feedback.scss","src/assets/stylesheets/main/layout/_footer.scss","src/assets/stylesheets/main/layout/_form.scss","src/assets/stylesheets/main/layout/_header.scss","src/assets/stylesheets/main/layout/_nav.scss","src/assets/stylesheets/main/layout/_search.scss","src/assets/stylesheets/main/layout/_select.scss","src/assets/stylesheets/main/layout/_sidebar.scss","src/assets/stylesheets/main/layout/_source.scss","src/assets/stylesheets/main/layout/_tabs.scss","src/assets/stylesheets/main/layout/_tag.scss","src/assets/stylesheets/main/layout/_tooltip.scss","src/assets/stylesheets/main/layout/_top.scss","src/assets/stylesheets/main/layout/_version.scss","src/assets/stylesheets/main/extensions/markdown/_admonition.scss","node_modules/material-design-color/material-color.scss","src/assets/stylesheets/main/extensions/markdown/_footnotes.scss","src/assets/stylesheets/main/extensions/markdown/_toc.scss","src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss","src/assets/stylesheets/main/extensions/pymdownx/_critic.scss","src/assets/stylesheets/main/extensions/pymdownx/_details.scss","src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss","src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss","src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss","src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss","src/assets/stylesheets/main/integrations/_mermaid.scss","src/assets/stylesheets/main/_modifiers.scss"],"names":[],"mappings":"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0B50FI,+EACE,wBAnBG,CAoBH,0C1B00FN,C0B50FI,mEACE,wBAnBG,CAoBH,kDAAA,CAAA,0C1B00FN,C0Bt0FI,oFACE,a1Bw0FN,C0Bz0FI,8EACE,a1Bw0FN,C0Bz0FI,kEACE,a1Bw0FN,C0Bx1FE,iFACE,oB1B21FJ,C0B51FE,2EACE,oB1B21FJ,C0B51FE,+DACE,oB1B21FJ,C0Bv1FE,wFACE,0B1B01FJ,C0B31FE,kFACE,0B1B01FJ,C0B31FE,sEACE,0B1B01FJ,C0Bv1FI,+FACE,wBAnBG,CAoBH,iDAAA,CAAA,yC1By1FN,C0B31FI,yFACE,wBAnBG,CAoBH,yC1By1FN,C0B31FI,6EACE,wBAnBG,CAoBH,iDAAA,CAAA,yC1By1FN,C0Br1FI,8FACE,a1Bu1FN,C0Bx1FI,wFACE,a1Bu1FN,C0Bx1FI,4EACE,a1Bu1FN,C0Bv2FE,iFACE,oB1B02FJ,C0B32FE,2EACE,oB1B02FJ,C0B32FE,+DACE,oB1B02FJ,C0Bt2FE,wFACE,0B1By2FJ,C0B12FE,kFACE,0B1By2FJ,C0B12FE,sEACE,0B1By2FJ,C0Bt2FI,+FACE,wBAnBG,CAoBH,qDAAA,CAAA,6C1Bw2FN,C0B12FI,yFACE,wBAnBG,CAoBH,6C1Bw2FN,C0B12FI,6EACE,wBAnBG,CAoBH,qDAAA,CAAA,6C1Bw2FN,C0Bp2FI,8FACE,a1Bs2FN,C0Bv2FI,wFACE,a1Bs2FN,C0Bv2FI,4EACE,a1Bs2FN,C0Bt3FE,gFACE,oB1By3FJ,C0B13FE,0EACE,oB1By3FJ,C0B13FE,8DACE,oB1By3FJ,C0Br3FE,uFACE,0B1Bw3FJ,C0Bz3FE,iFACE,0B1Bw3FJ,C0Bz3FE,qEACE,0B1Bw3FJ,C0Br3FI,8FACE,wBAnBG,CAoBH,sDAAA,CAAA,8C1Bu3FN,C0Bz3FI,wFACE,wBAnBG,CAoBH,8C1Bu3FN,C0Bz3FI,4EACE,wBAnBG,CAoBH,sDAAA,CAAA,8C1Bu3FN,C0Bn3FI,6FACE,a1Bq3FN,C0Bt3FI,uFACE,a1Bq3FN,C0Bt3FI,2EACE,a1Bq3FN,C0Br4FE,wFACE,oB1Bw4FJ,C0Bz4FE,kFACE,oB1Bw4FJ,C0Bz4FE,sEACE,oB1Bw4FJ,C0Bp4FE,+FACE,0B1Bu4FJ,C0Bx4FE,yFACE,0B1Bu4FJ,C0Bx4FE,6EACE,0B1Bu4FJ,C0Bp4FI,sGACE,wBAnBG,CAoBH,qDAAA,CAAA,6C1Bs4FN,C0Bx4FI,gGACE,wBAnBG,CAoBH,6C1Bs4FN,C0Bx4FI,oFACE,wBAnBG,CAoBH,qDAAA,CAAA,6C1Bs4FN,C0Bl4FI,qGACE,a1Bo4FN,C0Br4FI,+FACE,a1Bo4FN,C0Br4FI,mFACE,a1Bo4FN,C0Bp5FE,mFACE,oB1Bu5FJ,C0Bx5FE,6EACE,oB1Bu5FJ,C0Bx5FE,iEACE,oB1Bu5FJ,C0Bn5FE,0FACE,0B1Bs5FJ,C0Bv5FE,oFACE,0B1Bs5FJ,C0Bv5FE,wEACE,0B1Bs5FJ,C0Bn5FI,iGACE,wBAnBG,CAoBH,qDAAA,CAAA,6C1Bq5FN,C0Bv5FI,2FACE,wBAnBG,CAoBH,6C1Bq5FN,C0Bv5FI,+EACE,wBAnBG,CAoBH,qDAAA,CAAA,6C1Bq5FN,C0Bj5FI,gGACE,a1Bm5FN,C0Bp5FI,0FACE,a1Bm5FN,C0Bp5FI,8EACE,a1Bm5FN,C0Bn6FE,0EACE,oB1Bs6FJ,C0Bv6FE,oEACE,oB1Bs6FJ,C0Bv6FE,wDACE,oB1Bs6FJ,C0Bl6FE,iFACE,0B1Bq6FJ,C0Bt6FE,2EACE,0B1Bq6FJ,C0Bt6FE,+DACE,0B1Bq6FJ,C0Bl6FI,wFACE,wBAnBG,CAoBH,oDAAA,CAAA,4C1Bo6FN,C0Bt6FI,kFACE,wBAnBG,CAoBH,4C1Bo6FN,C0Bt6FI,sEACE,wBAnBG,CAoBH,oDAAA,CAAA,4C1Bo6FN,C0Bh6FI,uFACE,a1Bk6FN,C0Bn6FI,iFACE,a1Bk6FN,C0Bn6FI,qEACE,a1Bk6FN,C0Bl7FE,gEACE,oB1Bq7FJ,C0Bt7FE,0DACE,oB1Bq7FJ,C0Bt7FE,8CACE,oB1Bq7FJ,C0Bj7FE,uEACE,0B1Bo7FJ,C0Br7FE,iEACE,0B1Bo7FJ,C0Br7FE,qDACE,0B1Bo7FJ,C0Bj7FI,8EACE,wBAnBG,CAoBH,iDAAA,CAAA,yC1Bm7FN,C0Br7FI,wEACE,wBAnBG,CAoBH,yC1Bm7FN,C0Br7FI,4DACE,wBAnBG,CAoBH,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","file":"main.css"} \ No newline at end of file diff --git a/assets/stylesheets/palette.2505c338.min.css b/assets/stylesheets/palette.2505c338.min.css new file mode 100644 index 000000000..3c005dd68 --- /dev/null +++ b/assets/stylesheets/palette.2505c338.min.css @@ -0,0 +1 @@ +@media screen{[data-md-color-scheme=slate]{--md-hue:232;--md-default-fg-color:hsla(var(--md-hue),75%,95%,1);--md-default-fg-color--light:hsla(var(--md-hue),75%,90%,0.62);--md-default-fg-color--lighter:hsla(var(--md-hue),75%,90%,0.32);--md-default-fg-color--lightest:hsla(var(--md-hue),75%,90%,0.12);--md-default-bg-color:hsla(var(--md-hue),15%,21%,1);--md-default-bg-color--light:hsla(var(--md-hue),15%,21%,0.54);--md-default-bg-color--lighter:hsla(var(--md-hue),15%,21%,0.26);--md-default-bg-color--lightest:hsla(var(--md-hue),15%,21%,0.07);--md-code-fg-color:hsla(var(--md-hue),18%,86%,1);--md-code-bg-color:hsla(var(--md-hue),15%,15%,1);--md-code-hl-color:#4287ff26;--md-code-hl-number-color:#e6695b;--md-code-hl-special-color:#f06090;--md-code-hl-function-color:#c973d9;--md-code-hl-constant-color:#9383e2;--md-code-hl-keyword-color:#6791e0;--md-code-hl-string-color:#2fb170;--md-code-hl-name-color:var(--md-code-fg-color);--md-code-hl-operator-color:var(--md-default-fg-color--light);--md-code-hl-punctuation-color:var(--md-default-fg-color--light);--md-code-hl-comment-color:var(--md-default-fg-color--light);--md-code-hl-generic-color:var(--md-default-fg-color--light);--md-code-hl-variable-color:var(--md-default-fg-color--light);--md-typeset-color:var(--md-default-fg-color);--md-typeset-a-color:var(--md-primary-fg-color);--md-typeset-mark-color:#4287ff4d;--md-typeset-kbd-color:hsla(var(--md-hue),15%,94%,0.12);--md-typeset-kbd-accent-color:hsla(var(--md-hue),15%,94%,0.2);--md-typeset-kbd-border-color:hsla(var(--md-hue),15%,14%,1);--md-typeset-table-color:hsla(var(--md-hue),75%,95%,0.12);--md-admonition-fg-color:var(--md-default-fg-color);--md-admonition-bg-color:var(--md-default-bg-color);--md-footer-bg-color:hsla(var(--md-hue),15%,12%,0.87);--md-footer-bg-color--dark:hsla(var(--md-hue),15%,10%,1);--md-shadow-z1:0 0.2rem 0.5rem #0003,0 0 0.05rem #0000001a;--md-shadow-z2:0 0.2rem 0.5rem #0000004d,0 0 0.05rem #00000040;--md-shadow-z3:0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059}[data-md-color-scheme=slate] img[src$="#gh-light-mode-only"],[data-md-color-scheme=slate] img[src$="#only-light"]{display:none}[data-md-color-scheme=slate] img[src$="#gh-dark-mode-only"],[data-md-color-scheme=slate] img[src$="#only-dark"]{display:initial}[data-md-color-scheme=slate][data-md-color-primary=pink]{--md-typeset-a-color:#ed5487}[data-md-color-scheme=slate][data-md-color-primary=purple]{--md-typeset-a-color:#bd78c9}[data-md-color-scheme=slate][data-md-color-primary=deep-purple]{--md-typeset-a-color:#a682e3}[data-md-color-scheme=slate][data-md-color-primary=indigo]{--md-typeset-a-color:#6c91d5}[data-md-color-scheme=slate][data-md-color-primary=teal]{--md-typeset-a-color:#00ccb8}[data-md-color-scheme=slate][data-md-color-primary=green]{--md-typeset-a-color:#71c174}[data-md-color-scheme=slate][data-md-color-primary=deep-orange]{--md-typeset-a-color:#ff9575}[data-md-color-scheme=slate][data-md-color-primary=brown]{--md-typeset-a-color:#c7846b}[data-md-color-scheme=slate][data-md-color-primary=black],[data-md-color-scheme=slate][data-md-color-primary=blue-grey],[data-md-color-scheme=slate][data-md-color-primary=grey],[data-md-color-scheme=slate][data-md-color-primary=white]{--md-typeset-a-color:#6c91d5}[data-md-color-switching] *,[data-md-color-switching] :after,[data-md-color-switching] :before{transition-duration:0ms!important}}[data-md-color-accent=red]{--md-accent-fg-color:#ff1947;--md-accent-fg-color--transparent:#ff19471a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=pink]{--md-accent-fg-color:#f50056;--md-accent-fg-color--transparent:#f500561a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=purple]{--md-accent-fg-color:#df41fb;--md-accent-fg-color--transparent:#df41fb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=deep-purple]{--md-accent-fg-color:#7c4dff;--md-accent-fg-color--transparent:#7c4dff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=indigo]{--md-accent-fg-color:#526cfe;--md-accent-fg-color--transparent:#526cfe1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=blue]{--md-accent-fg-color:#4287ff;--md-accent-fg-color--transparent:#4287ff1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-blue]{--md-accent-fg-color:#0091eb;--md-accent-fg-color--transparent:#0091eb1a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=cyan]{--md-accent-fg-color:#00bad6;--md-accent-fg-color--transparent:#00bad61a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=teal]{--md-accent-fg-color:#00bda4;--md-accent-fg-color--transparent:#00bda41a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=green]{--md-accent-fg-color:#00c753;--md-accent-fg-color--transparent:#00c7531a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=light-green]{--md-accent-fg-color:#63de17;--md-accent-fg-color--transparent:#63de171a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-accent=lime]{--md-accent-fg-color:#b0eb00;--md-accent-fg-color--transparent:#b0eb001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=yellow]{--md-accent-fg-color:#ffd500;--md-accent-fg-color--transparent:#ffd5001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=amber]{--md-accent-fg-color:#fa0;--md-accent-fg-color--transparent:#ffaa001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=orange]{--md-accent-fg-color:#ff9100;--md-accent-fg-color--transparent:#ff91001a;--md-accent-bg-color:#000000de;--md-accent-bg-color--light:#0000008a}[data-md-color-accent=deep-orange]{--md-accent-fg-color:#ff6e42;--md-accent-fg-color--transparent:#ff6e421a;--md-accent-bg-color:#fff;--md-accent-bg-color--light:#ffffffb3}[data-md-color-primary=red]{--md-primary-fg-color:#ef5552;--md-primary-fg-color--light:#e57171;--md-primary-fg-color--dark:#e53734;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=pink]{--md-primary-fg-color:#e92063;--md-primary-fg-color--light:#ec417a;--md-primary-fg-color--dark:#c3185d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=purple]{--md-primary-fg-color:#ab47bd;--md-primary-fg-color--light:#bb69c9;--md-primary-fg-color--dark:#8c24a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=deep-purple]{--md-primary-fg-color:#7e56c2;--md-primary-fg-color--light:#9574cd;--md-primary-fg-color--dark:#673ab6;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=indigo]{--md-primary-fg-color:#4051b5;--md-primary-fg-color--light:#5d6cc0;--md-primary-fg-color--dark:#303fa1;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=blue]{--md-primary-fg-color:#2094f3;--md-primary-fg-color--light:#42a5f5;--md-primary-fg-color--dark:#1975d2;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-blue]{--md-primary-fg-color:#02a6f2;--md-primary-fg-color--light:#28b5f6;--md-primary-fg-color--dark:#0287cf;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=cyan]{--md-primary-fg-color:#00bdd6;--md-primary-fg-color--light:#25c5da;--md-primary-fg-color--dark:#0097a8;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=teal]{--md-primary-fg-color:#009485;--md-primary-fg-color--light:#26a699;--md-primary-fg-color--dark:#007a6c;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=green]{--md-primary-fg-color:#4cae4f;--md-primary-fg-color--light:#68bb6c;--md-primary-fg-color--dark:#398e3d;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=light-green]{--md-primary-fg-color:#8bc34b;--md-primary-fg-color--light:#9ccc66;--md-primary-fg-color--dark:#689f38;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=lime]{--md-primary-fg-color:#cbdc38;--md-primary-fg-color--light:#d3e156;--md-primary-fg-color--dark:#b0b52c;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=yellow]{--md-primary-fg-color:#ffec3d;--md-primary-fg-color--light:#ffee57;--md-primary-fg-color--dark:#fbc02d;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=amber]{--md-primary-fg-color:#ffc105;--md-primary-fg-color--light:#ffc929;--md-primary-fg-color--dark:#ffa200;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=orange]{--md-primary-fg-color:#ffa724;--md-primary-fg-color--light:#ffa724;--md-primary-fg-color--dark:#fa8900;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a}[data-md-color-primary=deep-orange]{--md-primary-fg-color:#ff6e42;--md-primary-fg-color--light:#ff8a66;--md-primary-fg-color--dark:#f4511f;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=brown]{--md-primary-fg-color:#795649;--md-primary-fg-color--light:#8d6e62;--md-primary-fg-color--dark:#5d4037;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3}[data-md-color-primary=grey]{--md-primary-fg-color:#757575;--md-primary-fg-color--light:#9e9e9e;--md-primary-fg-color--dark:#616161;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=blue-grey]{--md-primary-fg-color:#546d78;--md-primary-fg-color--light:#607c8a;--md-primary-fg-color--dark:#455a63;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=light-green]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#72ad2e}[data-md-color-primary=lime]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#8b990a}[data-md-color-primary=yellow]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#b8a500}[data-md-color-primary=amber]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#d19d00}[data-md-color-primary=orange]:not([data-md-color-scheme=slate]){--md-typeset-a-color:#e68a00}[data-md-color-primary=white]{--md-primary-fg-color:#fff;--md-primary-fg-color--light:#ffffffb3;--md-primary-fg-color--dark:#00000012;--md-primary-bg-color:#000000de;--md-primary-bg-color--light:#0000008a;--md-typeset-a-color:#4051b5}[data-md-color-primary=white] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=white] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:#fff}@media screen and (min-width:60em){[data-md-color-primary=white] .md-search__form{background-color:#00000012}[data-md-color-primary=white] .md-search__form:hover{background-color:#00000052}[data-md-color-primary=white] .md-search__input+.md-search__icon{color:#000000de}}@media screen and (min-width:76.25em){[data-md-color-primary=white] .md-tabs{border-bottom:.05rem solid #00000012}}[data-md-color-primary=black]{--md-primary-fg-color:#000;--md-primary-fg-color--light:#0000008a;--md-primary-fg-color--dark:#000;--md-primary-bg-color:#fff;--md-primary-bg-color--light:#ffffffb3;--md-typeset-a-color:#4051b5}[data-md-color-primary=black] .md-button{color:var(--md-typeset-a-color)}[data-md-color-primary=black] .md-button--primary{background-color:var(--md-typeset-a-color);border-color:var(--md-typeset-a-color);color:#fff}[data-md-color-primary=black] .md-header{background-color:#000}@media screen and (max-width:59.9375em){[data-md-color-primary=black] .md-nav__source{background-color:#000000de}}@media screen and (min-width:60em){[data-md-color-primary=black] .md-search__form{background-color:#ffffff1f}[data-md-color-primary=black] .md-search__form:hover{background-color:#ffffff4d}}@media screen and (max-width:76.1875em){html [data-md-color-primary=black] .md-nav--primary .md-nav__title[for=__drawer]{background-color:#000}}@media screen and (min-width:76.25em){[data-md-color-primary=black] .md-tabs{background-color:#000}} \ No newline at end of file diff --git a/assets/stylesheets/palette.2505c338.min.css.map b/assets/stylesheets/palette.2505c338.min.css.map new file mode 100644 index 000000000..3aec19034 --- /dev/null +++ b/assets/stylesheets/palette.2505c338.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/assets/stylesheets/palette/_scheme.scss","../../../src/assets/stylesheets/palette.scss","src/assets/stylesheets/palette/_accent.scss","src/assets/stylesheets/palette/_primary.scss","src/assets/stylesheets/utilities/_break.scss"],"names":[],"mappings":"AA2BA,cAGE,6BAKE,YAAA,CAGA,mDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CACA,mDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CAGA,gDAAA,CACA,gDAAA,CAGA,4BAAA,CACA,iCAAA,CACA,kCAAA,CACA,mCAAA,CACA,mCAAA,CACA,kCAAA,CACA,iCAAA,CACA,+CAAA,CACA,6DAAA,CACA,gEAAA,CACA,4DAAA,CACA,4DAAA,CACA,6DAAA,CAGA,6CAAA,CAGA,+CAAA,CAGA,iCAAA,CAGA,uDAAA,CACA,6DAAA,CACA,2DAAA,CAGA,yDAAA,CAGA,mDAAA,CACA,mDAAA,CAGA,qDAAA,CACA,wDAAA,CAGA,0DAAA,CAKA,8DAAA,CAKA,0DCxDF,CD6DE,kHAEE,YC3DJ,CD+DE,gHAEE,eC7DJ,CDoFE,yDACE,4BClFJ,CDiFE,2DACE,4BC/EJ,CD8EE,gEACE,4BC5EJ,CD2EE,2DACE,4BCzEJ,CDwEE,yDACE,4BCtEJ,CDqEE,0DACE,4BCnEJ,CDkEE,gEACE,4BChEJ,CD+DE,0DACE,4BC7DJ,CD4DE,2OACE,4BCjDJ,CDwDA,+FAGE,iCCtDF,CACF,CCjDE,2BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD6CN,CCvDE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDoDN,CC9DE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD2DN,CCrEE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDkEN,CC5EE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDyEN,CCnFE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDgFN,CC1FE,kCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDuFN,CCjGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD8FN,CCxGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDqGN,CC/GE,6BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD4GN,CCtHE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDmHN,CC7HE,4BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD6HN,CCpIE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDoIN,CC3IE,6BACE,yBAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD2IN,CClJE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDkJN,CCzJE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDsJN,CE3JE,4BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwJN,CEnKE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgKN,CE3KE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwKN,CEnLE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgLN,CE3LE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwLN,CEnME,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgMN,CE3ME,mCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwMN,CEnNE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgNN,CE3NE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwNN,CEnOE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgON,CE3OE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwON,CEnPE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFmPN,CE3PE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCF2PN,CEnQE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFmQN,CE3QE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCF2QN,CEnRE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFgRN,CE3RE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFwRN,CEnSE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BF4RN,CE5SE,kCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BFqSN,CEtRE,sEACE,4BFyRJ,CE1RE,+DACE,4BF6RJ,CE9RE,iEACE,4BFiSJ,CElSE,gEACE,4BFqSJ,CEtSE,iEACE,4BFySJ,CEhSA,8BACE,0BAAA,CACA,sCAAA,CACA,qCAAA,CACA,+BAAA,CACA,sCAAA,CAGA,4BFiSF,CE9RE,yCACE,+BFgSJ,CE7RI,kDAEE,0CAAA,CACA,sCAAA,CAFA,UFiSN,CG7MI,mCD1EA,+CACE,0BF0RJ,CEvRI,qDACE,0BFyRN,CEpRE,iEACE,eFsRJ,CACF,CGxNI,sCDvDA,uCACE,oCFkRJ,CACF,CEzQA,8BACE,0BAAA,CACA,sCAAA,CACA,gCAAA,CACA,0BAAA,CACA,sCAAA,CAGA,4BF0QF,CEvQE,yCACE,+BFyQJ,CEtQI,kDAEE,0CAAA,CACA,sCAAA,CAFA,UF0QN,CEnQE,yCACE,qBFqQJ,CG9NI,wCDhCA,8CACE,0BFiQJ,CACF,CGtPI,mCDJA,+CACE,0BF6PJ,CE1PI,qDACE,0BF4PN,CACF,CG3OI,wCDTA,iFACE,qBFuPJ,CACF,CGnQI,sCDmBA,uCACE,qBFmPJ,CACF","file":"palette.css"} \ No newline at end of file diff --git a/css/custom.css b/css/custom.css new file mode 100644 index 000000000..7a1008b0b --- /dev/null +++ b/css/custom.css @@ -0,0 +1,4 @@ +/* disable ligatures in code and preformatted blocks */ +code, pre { + font-variant-ligatures: none; +} diff --git a/examples/README.cpp b/examples/README.cpp new file mode 100644 index 000000000..2d641e587 --- /dev/null +++ b/examples/README.cpp @@ -0,0 +1,39 @@ +#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'; +} diff --git a/examples/README.output b/examples/README.output new file mode 100644 index 000000000..31188d45e --- /dev/null +++ b/examples/README.output @@ -0,0 +1,27 @@ +{ + "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 +} diff --git a/examples/accept__string.cpp b/examples/accept__string.cpp new file mode 100644 index 000000000..8eb3d9b75 --- /dev/null +++ b/examples/accept__string.cpp @@ -0,0 +1,26 @@ +#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'; +} diff --git a/examples/accept__string.output b/examples/accept__string.output new file mode 100644 index 000000000..836a5934c --- /dev/null +++ b/examples/accept__string.output @@ -0,0 +1 @@ +true false diff --git a/examples/array.cpp b/examples/array.cpp new file mode 100644 index 000000000..139b5ef10 --- /dev/null +++ b/examples/array.cpp @@ -0,0 +1,19 @@ +#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'; +} diff --git a/examples/array.output b/examples/array.output new file mode 100644 index 000000000..4e75a1b67 --- /dev/null +++ b/examples/array.output @@ -0,0 +1,4 @@ +[] +[] +[1,2,3,4] +[["one",1],["two",2]] diff --git a/examples/array_t.cpp b/examples/array_t.cpp new file mode 100644 index 000000000..0964857b7 --- /dev/null +++ b/examples/array_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same, json::array_t>::value << std::endl; +} diff --git a/examples/array_t.output b/examples/array_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/array_t.output @@ -0,0 +1 @@ +true diff --git a/examples/at__json_pointer.cpp b/examples/at__json_pointer.cpp new file mode 100644 index 000000000..26dfd8edd --- /dev/null +++ b/examples/at__json_pointer.cpp @@ -0,0 +1,104 @@ +#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 (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 (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 (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 (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 (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 (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/at__json_pointer.output b/examples/at__json_pointer.output new file mode 100644 index 000000000..1d29893e4 --- /dev/null +++ b/examples/at__json_pointer.output @@ -0,0 +1,12 @@ +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' diff --git a/examples/at__json_pointer_const.cpp b/examples/at__json_pointer_const.cpp new file mode 100644 index 000000000..f049bd8d9 --- /dev/null +++ b/examples/at__json_pointer_const.cpp @@ -0,0 +1,80 @@ +#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 (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 (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 (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 (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 (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/at__json_pointer_const.output b/examples/at__json_pointer_const.output new file mode 100644 index 000000000..aaf8f1871 --- /dev/null +++ b/examples/at__json_pointer_const.output @@ -0,0 +1,9 @@ +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' diff --git a/examples/at__keytype.c++17.cpp b/examples/at__keytype.c++17.cpp new file mode 100644 index 000000000..3491cb9f7 --- /dev/null +++ b/examples/at__keytype.c++17.cpp @@ -0,0 +1,50 @@ +#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 (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 (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/at__keytype.c++17.output b/examples/at__keytype.c++17.output new file mode 100644 index 000000000..b544b7299 --- /dev/null +++ b/examples/at__keytype.c++17.output @@ -0,0 +1,4 @@ +"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 diff --git a/examples/at__keytype_const.c++17.cpp b/examples/at__keytype_const.c++17.cpp new file mode 100644 index 000000000..ec93c7059 --- /dev/null +++ b/examples/at__keytype_const.c++17.cpp @@ -0,0 +1,44 @@ +#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 (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 (json::out_of_range) + { + std::cout << "out of range" << '\n'; + } +} diff --git a/examples/at__keytype_const.c++17.output b/examples/at__keytype_const.c++17.output new file mode 100644 index 000000000..40ca3f09f --- /dev/null +++ b/examples/at__keytype_const.c++17.output @@ -0,0 +1,3 @@ +"il brutto" +[json.exception.type_error.304] cannot use at() with string +out of range diff --git a/examples/at__object_t_key_type.cpp b/examples/at__object_t_key_type.cpp new file mode 100644 index 000000000..202f8a2ee --- /dev/null +++ b/examples/at__object_t_key_type.cpp @@ -0,0 +1,48 @@ +#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 (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 (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/at__object_t_key_type.output b/examples/at__object_t_key_type.output new file mode 100644 index 000000000..b544b7299 --- /dev/null +++ b/examples/at__object_t_key_type.output @@ -0,0 +1,4 @@ +"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 diff --git a/examples/at__object_t_key_type_const.cpp b/examples/at__object_t_key_type_const.cpp new file mode 100644 index 000000000..e5244f3f7 --- /dev/null +++ b/examples/at__object_t_key_type_const.cpp @@ -0,0 +1,42 @@ +#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 (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 (json::out_of_range) + { + std::cout << "out of range" << '\n'; + } +} diff --git a/examples/at__object_t_key_type_const.output b/examples/at__object_t_key_type_const.output new file mode 100644 index 000000000..40ca3f09f --- /dev/null +++ b/examples/at__object_t_key_type_const.output @@ -0,0 +1,3 @@ +"il brutto" +[json.exception.type_error.304] cannot use at() with string +out of range diff --git a/examples/at__size_type.cpp b/examples/at__size_type.cpp new file mode 100644 index 000000000..65baeddcf --- /dev/null +++ b/examples/at__size_type.cpp @@ -0,0 +1,43 @@ +#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 (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 (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/at__size_type.output b/examples/at__size_type.output new file mode 100644 index 000000000..54026436f --- /dev/null +++ b/examples/at__size_type.output @@ -0,0 +1,4 @@ +"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 diff --git a/examples/at__size_type_const.cpp b/examples/at__size_type_const.cpp new file mode 100644 index 000000000..faa4cffdd --- /dev/null +++ b/examples/at__size_type_const.cpp @@ -0,0 +1,37 @@ +#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 (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 (json::out_of_range& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/at__size_type_const.output b/examples/at__size_type_const.output new file mode 100644 index 000000000..8135a27a5 --- /dev/null +++ b/examples/at__size_type_const.output @@ -0,0 +1,3 @@ +"third" +[json.exception.type_error.304] cannot use at() with string +[json.exception.out_of_range.401] array index 5 is out of range diff --git a/examples/back.cpp b/examples/back.cpp new file mode 100644 index 000000000..1439a8218 --- /dev/null +++ b/examples/back.cpp @@ -0,0 +1,38 @@ +#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 (json::invalid_iterator& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/back.output b/examples/back.output new file mode 100644 index 000000000..2990dbf0e --- /dev/null +++ b/examples/back.output @@ -0,0 +1,7 @@ +true +17 +23.42 +2 +16 +"Hello, world" +[json.exception.invalid_iterator.214] cannot get value diff --git a/examples/basic_json__CompatibleType.cpp b/examples/basic_json__CompatibleType.cpp new file mode 100644 index 000000000..e2f01aa63 --- /dev/null +++ b/examples/basic_json__CompatibleType.cpp @@ -0,0 +1,218 @@ +#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'; +} diff --git a/examples/basic_json__CompatibleType.output b/examples/basic_json__CompatibleType.output new file mode 100644 index 000000000..2337e81fb --- /dev/null +++ b/examples/basic_json__CompatibleType.output @@ -0,0 +1,39 @@ +{"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 diff --git a/examples/basic_json__InputIt_InputIt.cpp b/examples/basic_json__InputIt_InputIt.cpp new file mode 100644 index 000000000..ed5aff9a8 --- /dev/null +++ b/examples/basic_json__InputIt_InputIt.cpp @@ -0,0 +1,32 @@ +#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 (json::invalid_iterator& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/basic_json__InputIt_InputIt.output b/examples/basic_json__InputIt_InputIt.output new file mode 100644 index 000000000..bfb017785 --- /dev/null +++ b/examples/basic_json__InputIt_InputIt.output @@ -0,0 +1,4 @@ +["bravo","charly"] +42 +{"one":"eins"} +[json.exception.invalid_iterator.204] iterators out of range diff --git a/examples/basic_json__basic_json.cpp b/examples/basic_json__basic_json.cpp new file mode 100644 index 000000000..17136f437 --- /dev/null +++ b/examples/basic_json__basic_json.cpp @@ -0,0 +1,17 @@ +#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'; +} diff --git a/examples/basic_json__basic_json.output b/examples/basic_json__basic_json.output new file mode 100644 index 000000000..ee93a41ca --- /dev/null +++ b/examples/basic_json__basic_json.output @@ -0,0 +1,2 @@ +["one","two",3,4.5,false] = ["one","two",3,4.5,false] +true diff --git a/examples/basic_json__copyassignment.cpp b/examples/basic_json__copyassignment.cpp new file mode 100644 index 000000000..2d8657400 --- /dev/null +++ b/examples/basic_json__copyassignment.cpp @@ -0,0 +1,18 @@ +#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'; +} diff --git a/examples/basic_json__copyassignment.output b/examples/basic_json__copyassignment.output new file mode 100644 index 000000000..c1eee2105 --- /dev/null +++ b/examples/basic_json__copyassignment.output @@ -0,0 +1,2 @@ +23 +23 diff --git a/examples/basic_json__list_init_t.cpp b/examples/basic_json__list_init_t.cpp new file mode 100644 index 000000000..78611e1a3 --- /dev/null +++ b/examples/basic_json__list_init_t.cpp @@ -0,0 +1,21 @@ +#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'; +} diff --git a/examples/basic_json__list_init_t.output b/examples/basic_json__list_init_t.output new file mode 100644 index 000000000..d38f5b842 --- /dev/null +++ b/examples/basic_json__list_init_t.output @@ -0,0 +1,5 @@ +{} +{"one":1,"two":2} +[1,2,3,4] +{"one":[1],"two":[1,2]} +[[[1],"one"],[[1,2],"two"]] diff --git a/examples/basic_json__moveconstructor.cpp b/examples/basic_json__moveconstructor.cpp new file mode 100644 index 000000000..48b68f61e --- /dev/null +++ b/examples/basic_json__moveconstructor.cpp @@ -0,0 +1,17 @@ +#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'; +} diff --git a/examples/basic_json__moveconstructor.output b/examples/basic_json__moveconstructor.output new file mode 100644 index 000000000..911b5b1ac --- /dev/null +++ b/examples/basic_json__moveconstructor.output @@ -0,0 +1,2 @@ +null +23 diff --git a/examples/basic_json__nullptr_t.cpp b/examples/basic_json__nullptr_t.cpp new file mode 100644 index 000000000..7a4366650 --- /dev/null +++ b/examples/basic_json__nullptr_t.cpp @@ -0,0 +1,16 @@ +#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'; +} diff --git a/examples/basic_json__nullptr_t.output b/examples/basic_json__nullptr_t.output new file mode 100644 index 000000000..c1e4b6c17 --- /dev/null +++ b/examples/basic_json__nullptr_t.output @@ -0,0 +1,2 @@ +null +null diff --git a/examples/basic_json__size_type_basic_json.cpp b/examples/basic_json__size_type_basic_json.cpp new file mode 100644 index 000000000..9ec767727 --- /dev/null +++ b/examples/basic_json__size_type_basic_json.cpp @@ -0,0 +1,18 @@ +#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'; +} diff --git a/examples/basic_json__size_type_basic_json.output b/examples/basic_json__size_type_basic_json.output new file mode 100644 index 000000000..f4c59b348 --- /dev/null +++ b/examples/basic_json__size_type_basic_json.output @@ -0,0 +1,3 @@ +[] +["Hello"] +["Hello","Hello","Hello","Hello","Hello"] diff --git a/examples/basic_json__value_t.cpp b/examples/basic_json__value_t.cpp new file mode 100644 index 000000000..c306731ac --- /dev/null +++ b/examples/basic_json__value_t.cpp @@ -0,0 +1,25 @@ +#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'; +} diff --git a/examples/basic_json__value_t.output b/examples/basic_json__value_t.output new file mode 100644 index 000000000..ea542caeb --- /dev/null +++ b/examples/basic_json__value_t.output @@ -0,0 +1,7 @@ +null +false +0 +0.0 +{} +[] +"" diff --git a/examples/begin.cpp b/examples/begin.cpp new file mode 100644 index 000000000..654835b02 --- /dev/null +++ b/examples/begin.cpp @@ -0,0 +1,16 @@ +#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'; +} diff --git a/examples/begin.output b/examples/begin.output new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/examples/begin.output @@ -0,0 +1 @@ +1 diff --git a/examples/binary.cpp b/examples/binary.cpp new file mode 100644 index 000000000..617ce6096 --- /dev/null +++ b/examples/binary.cpp @@ -0,0 +1,16 @@ +#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; +} diff --git a/examples/binary.output b/examples/binary.output new file mode 100644 index 000000000..74b05d23f --- /dev/null +++ b/examples/binary.output @@ -0,0 +1 @@ +type: binary, subtype: 42 diff --git a/examples/binary_t.cpp b/examples/binary_t.cpp new file mode 100644 index 000000000..bfaee5ca8 --- /dev/null +++ b/examples/binary_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same>, json::binary_t>::value << std::endl; +} diff --git a/examples/binary_t.output b/examples/binary_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/binary_t.output @@ -0,0 +1 @@ +true diff --git a/examples/boolean_t.cpp b/examples/boolean_t.cpp new file mode 100644 index 000000000..75b8c99f9 --- /dev/null +++ b/examples/boolean_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/examples/boolean_t.output b/examples/boolean_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/boolean_t.output @@ -0,0 +1 @@ +true diff --git a/examples/byte_container_with_subtype__byte_container_with_subtype.cpp b/examples/byte_container_with_subtype__byte_container_with_subtype.cpp new file mode 100644 index 000000000..1c10be5c2 --- /dev/null +++ b/examples/byte_container_with_subtype__byte_container_with_subtype.cpp @@ -0,0 +1,23 @@ +#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; +} diff --git a/examples/byte_container_with_subtype__byte_container_with_subtype.output b/examples/byte_container_with_subtype__byte_container_with_subtype.output new file mode 100644 index 000000000..67ac1b2ef --- /dev/null +++ b/examples/byte_container_with_subtype__byte_container_with_subtype.output @@ -0,0 +1,3 @@ +{"bytes":[],"subtype":null} +{"bytes":[202,254,186,190],"subtype":null} +{"bytes":[202,254,186,190],"subtype":42} diff --git a/examples/byte_container_with_subtype__clear_subtype.cpp b/examples/byte_container_with_subtype__clear_subtype.cpp new file mode 100644 index 000000000..f9ce6842b --- /dev/null +++ b/examples/byte_container_with_subtype__clear_subtype.cpp @@ -0,0 +1,21 @@ +#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'; +} diff --git a/examples/byte_container_with_subtype__clear_subtype.output b/examples/byte_container_with_subtype__clear_subtype.output new file mode 100644 index 000000000..9d8212946 --- /dev/null +++ b/examples/byte_container_with_subtype__clear_subtype.output @@ -0,0 +1,2 @@ +before calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":42} +after calling clear_subtype(): {"bytes":[202,254,186,190],"subtype":null} diff --git a/examples/byte_container_with_subtype__has_subtype.cpp b/examples/byte_container_with_subtype__has_subtype.cpp new file mode 100644 index 000000000..61c21eaae --- /dev/null +++ b/examples/byte_container_with_subtype__has_subtype.cpp @@ -0,0 +1,19 @@ +#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; +} diff --git a/examples/byte_container_with_subtype__has_subtype.output b/examples/byte_container_with_subtype__has_subtype.output new file mode 100644 index 000000000..f4aade2a1 --- /dev/null +++ b/examples/byte_container_with_subtype__has_subtype.output @@ -0,0 +1,2 @@ +c1.has_subtype() = false +c2.has_subtype() = true diff --git a/examples/byte_container_with_subtype__set_subtype.cpp b/examples/byte_container_with_subtype__set_subtype.cpp new file mode 100644 index 000000000..b2694c54d --- /dev/null +++ b/examples/byte_container_with_subtype__set_subtype.cpp @@ -0,0 +1,22 @@ +#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'; +} diff --git a/examples/byte_container_with_subtype__set_subtype.output b/examples/byte_container_with_subtype__set_subtype.output new file mode 100644 index 000000000..648b3ef24 --- /dev/null +++ b/examples/byte_container_with_subtype__set_subtype.output @@ -0,0 +1,2 @@ +before calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":null} +after calling set_subtype(42): {"bytes":[202,254,186,190],"subtype":42} diff --git a/examples/byte_container_with_subtype__subtype.cpp b/examples/byte_container_with_subtype__subtype.cpp new file mode 100644 index 000000000..cd230ade1 --- /dev/null +++ b/examples/byte_container_with_subtype__subtype.cpp @@ -0,0 +1,22 @@ +#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)); +} diff --git a/examples/byte_container_with_subtype__subtype.output b/examples/byte_container_with_subtype__subtype.output new file mode 100644 index 000000000..47955277b --- /dev/null +++ b/examples/byte_container_with_subtype__subtype.output @@ -0,0 +1,2 @@ +c1.subtype() = 18446744073709551615 +c2.subtype() = 42 diff --git a/examples/cbegin.cpp b/examples/cbegin.cpp new file mode 100644 index 000000000..bed2b3725 --- /dev/null +++ b/examples/cbegin.cpp @@ -0,0 +1,16 @@ +#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'; +} diff --git a/examples/cbegin.output b/examples/cbegin.output new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/examples/cbegin.output @@ -0,0 +1 @@ +1 diff --git a/examples/cbor_tag_handler_t.cpp b/examples/cbor_tag_handler_t.cpp new file mode 100644 index 000000000..79052c7a0 --- /dev/null +++ b/examples/cbor_tag_handler_t.cpp @@ -0,0 +1,28 @@ +#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 (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; +} diff --git a/examples/cbor_tag_handler_t.output b/examples/cbor_tag_handler_t.output new file mode 100644 index 000000000..18920b137 --- /dev/null +++ b/examples/cbor_tag_handler_t.output @@ -0,0 +1,3 @@ +[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} diff --git a/examples/cend.cpp b/examples/cend.cpp new file mode 100644 index 000000000..3050f5001 --- /dev/null +++ b/examples/cend.cpp @@ -0,0 +1,19 @@ +#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'; +} diff --git a/examples/cend.output b/examples/cend.output new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/examples/cend.output @@ -0,0 +1 @@ +5 diff --git a/examples/clear.cpp b/examples/clear.cpp new file mode 100644 index 000000000..f081e7eda --- /dev/null +++ b/examples/clear.cpp @@ -0,0 +1,34 @@ +#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'; +} diff --git a/examples/clear.output b/examples/clear.output new file mode 100644 index 000000000..ea542caeb --- /dev/null +++ b/examples/clear.output @@ -0,0 +1,7 @@ +null +false +0 +0.0 +{} +[] +"" diff --git a/examples/contains__json_pointer.cpp b/examples/contains__json_pointer.cpp new file mode 100644 index 000000000..f9de546b5 --- /dev/null +++ b/examples/contains__json_pointer.cpp @@ -0,0 +1,43 @@ +#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 (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 (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/contains__json_pointer.output b/examples/contains__json_pointer.output new file mode 100644 index 000000000..dd1eb38c1 --- /dev/null +++ b/examples/contains__json_pointer.output @@ -0,0 +1,7 @@ +true +true +true +true +false +false +false diff --git a/examples/contains__keytype.c++17.cpp b/examples/contains__keytype.c++17.cpp new file mode 100644 index 000000000..43b62fab1 --- /dev/null +++ b/examples/contains__keytype.c++17.cpp @@ -0,0 +1,20 @@ +#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; +} diff --git a/examples/contains__keytype.c++17.output b/examples/contains__keytype.c++17.output new file mode 100644 index 000000000..14ad177b1 --- /dev/null +++ b/examples/contains__keytype.c++17.output @@ -0,0 +1,3 @@ +j_object contains 'key': true +j_object contains 'another': false +j_array contains 'key': false diff --git a/examples/contains__object_t_key_type.cpp b/examples/contains__object_t_key_type.cpp new file mode 100644 index 000000000..a8bc8143d --- /dev/null +++ b/examples/contains__object_t_key_type.cpp @@ -0,0 +1,18 @@ +#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; +} diff --git a/examples/contains__object_t_key_type.output b/examples/contains__object_t_key_type.output new file mode 100644 index 000000000..14ad177b1 --- /dev/null +++ b/examples/contains__object_t_key_type.output @@ -0,0 +1,3 @@ +j_object contains 'key': true +j_object contains 'another': false +j_array contains 'key': false diff --git a/examples/count__keytype.c++17.cpp b/examples/count__keytype.c++17.cpp new file mode 100644 index 000000000..ec6de0607 --- /dev/null +++ b/examples/count__keytype.c++17.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/count__keytype.c++17.output b/examples/count__keytype.c++17.output new file mode 100644 index 000000000..d816fcb24 --- /dev/null +++ b/examples/count__keytype.c++17.output @@ -0,0 +1,2 @@ +number of elements with key "two": 1 +number of elements with key "three": 0 diff --git a/examples/count__object_t_key_type.cpp b/examples/count__object_t_key_type.cpp new file mode 100644 index 000000000..a8d54b9d1 --- /dev/null +++ b/examples/count__object_t_key_type.cpp @@ -0,0 +1,18 @@ +#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'; +} diff --git a/examples/count__object_t_key_type.output b/examples/count__object_t_key_type.output new file mode 100644 index 000000000..d816fcb24 --- /dev/null +++ b/examples/count__object_t_key_type.output @@ -0,0 +1,2 @@ +number of elements with key "two": 1 +number of elements with key "three": 0 diff --git a/examples/crbegin.cpp b/examples/crbegin.cpp new file mode 100644 index 000000000..dc3209cf8 --- /dev/null +++ b/examples/crbegin.cpp @@ -0,0 +1,16 @@ +#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'; +} diff --git a/examples/crbegin.output b/examples/crbegin.output new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/examples/crbegin.output @@ -0,0 +1 @@ +5 diff --git a/examples/crend.cpp b/examples/crend.cpp new file mode 100644 index 000000000..dff260931 --- /dev/null +++ b/examples/crend.cpp @@ -0,0 +1,19 @@ +#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'; +} diff --git a/examples/crend.output b/examples/crend.output new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/examples/crend.output @@ -0,0 +1 @@ +1 diff --git a/examples/default_object_comparator_t.cpp b/examples/default_object_comparator_t.cpp new file mode 100644 index 000000000..9f200fe6b --- /dev/null +++ b/examples/default_object_comparator_t.cpp @@ -0,0 +1,11 @@ +#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; +} diff --git a/examples/default_object_comparator_t.output b/examples/default_object_comparator_t.output new file mode 100644 index 000000000..b1daf3b96 --- /dev/null +++ b/examples/default_object_comparator_t.output @@ -0,0 +1,2 @@ +one < two : true +three < four : false diff --git a/examples/diagnostics_extended.cpp b/examples/diagnostics_extended.cpp new file mode 100644 index 000000000..f4c43f05e --- /dev/null +++ b/examples/diagnostics_extended.cpp @@ -0,0 +1,22 @@ +#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 (json::exception& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/diagnostics_extended.output b/examples/diagnostics_extended.output new file mode 100644 index 000000000..f142927a1 --- /dev/null +++ b/examples/diagnostics_extended.output @@ -0,0 +1 @@ +[json.exception.type_error.302] (/address/housenumber) type must be number, but is string diff --git a/examples/diagnostics_standard.cpp b/examples/diagnostics_standard.cpp new file mode 100644 index 000000000..575c409eb --- /dev/null +++ b/examples/diagnostics_standard.cpp @@ -0,0 +1,20 @@ +#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 (json::exception& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/diagnostics_standard.output b/examples/diagnostics_standard.output new file mode 100644 index 000000000..79707a0cb --- /dev/null +++ b/examples/diagnostics_standard.output @@ -0,0 +1 @@ +[json.exception.type_error.302] type must be number, but is string diff --git a/examples/diff.cpp b/examples/diff.cpp new file mode 100644 index 000000000..ef01332a1 --- /dev/null +++ b/examples/diff.cpp @@ -0,0 +1,37 @@ +#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; +} diff --git a/examples/diff.output b/examples/diff.output new file mode 100644 index 000000000..7dc79791f --- /dev/null +++ b/examples/diff.output @@ -0,0 +1,25 @@ +[ + { + "op": "replace", + "path": "/baz", + "value": "boo" + }, + { + "op": "remove", + "path": "/foo" + }, + { + "op": "add", + "path": "/hello", + "value": [ + "world" + ] + } +] + +{ + "baz": "boo", + "hello": [ + "world" + ] +} diff --git a/examples/dump.cpp b/examples/dump.cpp new file mode 100644 index 000000000..eb2d71f0e --- /dev/null +++ b/examples/dump.cpp @@ -0,0 +1,48 @@ +#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 (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'; +} diff --git a/examples/dump.output b/examples/dump.output new file mode 100644 index 000000000..43009fe62 --- /dev/null +++ b/examples/dump.output @@ -0,0 +1,55 @@ +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: "äü" diff --git a/examples/emplace.cpp b/examples/emplace.cpp new file mode 100644 index 000000000..a5314910f --- /dev/null +++ b/examples/emplace.cpp @@ -0,0 +1,31 @@ +#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'; +} diff --git a/examples/emplace.output b/examples/emplace.output new file mode 100644 index 000000000..83d6f7730 --- /dev/null +++ b/examples/emplace.output @@ -0,0 +1,6 @@ +{"one":1,"two":2} +null +{"one":1,"three":3,"two":2} +3 true +{"A":"a","B":"b"} +"b" false diff --git a/examples/emplace_back.cpp b/examples/emplace_back.cpp new file mode 100644 index 000000000..e979a945c --- /dev/null +++ b/examples/emplace_back.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/emplace_back.output b/examples/emplace_back.output new file mode 100644 index 000000000..bdd80d82d --- /dev/null +++ b/examples/emplace_back.output @@ -0,0 +1,4 @@ +[1,2,3,4,5] +null +[1,2,3,4,5,6] +["first",["second","second","second"]] diff --git a/examples/empty.cpp b/examples/empty.cpp new file mode 100644 index 000000000..6ef6e40ed --- /dev/null +++ b/examples/empty.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/empty.output b/examples/empty.output new file mode 100644 index 000000000..d071a3980 --- /dev/null +++ b/examples/empty.output @@ -0,0 +1,9 @@ +true +false +false +false +false +true +false +true +false diff --git a/examples/end.cpp b/examples/end.cpp new file mode 100644 index 000000000..47beedb77 --- /dev/null +++ b/examples/end.cpp @@ -0,0 +1,19 @@ +#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'; +} diff --git a/examples/end.output b/examples/end.output new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/examples/end.output @@ -0,0 +1 @@ +5 diff --git a/examples/erase__IteratorType.cpp b/examples/erase__IteratorType.cpp new file mode 100644 index 000000000..f0d4ec6fb --- /dev/null +++ b/examples/erase__IteratorType.cpp @@ -0,0 +1,31 @@ +#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'; +} diff --git a/examples/erase__IteratorType.output b/examples/erase__IteratorType.output new file mode 100644 index 000000000..e392f8eaf --- /dev/null +++ b/examples/erase__IteratorType.output @@ -0,0 +1,6 @@ +null +null +null +{"one":1} +[1,2,8,16] +null diff --git a/examples/erase__IteratorType_IteratorType.cpp b/examples/erase__IteratorType_IteratorType.cpp new file mode 100644 index 000000000..392511ffe --- /dev/null +++ b/examples/erase__IteratorType_IteratorType.cpp @@ -0,0 +1,31 @@ +#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'; +} diff --git a/examples/erase__IteratorType_IteratorType.output b/examples/erase__IteratorType_IteratorType.output new file mode 100644 index 000000000..5d01f0089 --- /dev/null +++ b/examples/erase__IteratorType_IteratorType.output @@ -0,0 +1,6 @@ +null +null +null +{"one":1} +[1,8,16] +null diff --git a/examples/erase__keytype.c++17.cpp b/examples/erase__keytype.c++17.cpp new file mode 100644 index 000000000..c5e4bed5d --- /dev/null +++ b/examples/erase__keytype.c++17.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/erase__keytype.c++17.output b/examples/erase__keytype.c++17.output new file mode 100644 index 000000000..28d79391a --- /dev/null +++ b/examples/erase__keytype.c++17.output @@ -0,0 +1,2 @@ +{"two":2} +1 0 diff --git a/examples/erase__object_t_key_type.cpp b/examples/erase__object_t_key_type.cpp new file mode 100644 index 000000000..2fd84c86e --- /dev/null +++ b/examples/erase__object_t_key_type.cpp @@ -0,0 +1,18 @@ +#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'; +} diff --git a/examples/erase__object_t_key_type.output b/examples/erase__object_t_key_type.output new file mode 100644 index 000000000..28d79391a --- /dev/null +++ b/examples/erase__object_t_key_type.output @@ -0,0 +1,2 @@ +{"two":2} +1 0 diff --git a/examples/erase__size_type.cpp b/examples/erase__size_type.cpp new file mode 100644 index 000000000..810062387 --- /dev/null +++ b/examples/erase__size_type.cpp @@ -0,0 +1,16 @@ +#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'; +} diff --git a/examples/erase__size_type.output b/examples/erase__size_type.output new file mode 100644 index 000000000..4ad74061f --- /dev/null +++ b/examples/erase__size_type.output @@ -0,0 +1 @@ +[0,1,3,4,5] diff --git a/examples/error_handler_t.cpp b/examples/error_handler_t.cpp new file mode 100644 index 000000000..add3f3b2d --- /dev/null +++ b/examples/error_handler_t.cpp @@ -0,0 +1,24 @@ +#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 (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'; +} diff --git a/examples/error_handler_t.output b/examples/error_handler_t.output new file mode 100644 index 000000000..718d62bee --- /dev/null +++ b/examples/error_handler_t.output @@ -0,0 +1,3 @@ +[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9 +string with replaced invalid characters: "ä�ü" +string with ignored invalid characters: "äü" diff --git a/examples/exception.cpp b/examples/exception.cpp new file mode 100644 index 000000000..82696e614 --- /dev/null +++ b/examples/exception.cpp @@ -0,0 +1,20 @@ +#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 (json::exception& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/examples/exception.output b/examples/exception.output new file mode 100644 index 000000000..fa20df6e8 --- /dev/null +++ b/examples/exception.output @@ -0,0 +1,2 @@ +message: [json.exception.out_of_range.403] key 'non-existing' not found +exception id: 403 diff --git a/examples/find__keytype.c++17.cpp b/examples/find__keytype.c++17.cpp new file mode 100644 index 000000000..da94cf0ad --- /dev/null +++ b/examples/find__keytype.c++17.cpp @@ -0,0 +1,22 @@ +#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'; +} diff --git a/examples/find__keytype.c++17.output b/examples/find__keytype.c++17.output new file mode 100644 index 000000000..509bb42d5 --- /dev/null +++ b/examples/find__keytype.c++17.output @@ -0,0 +1,3 @@ +"two" was found: true +value at key "two": 2 +"three" was found: false diff --git a/examples/find__object_t_key_type.cpp b/examples/find__object_t_key_type.cpp new file mode 100644 index 000000000..685ba7763 --- /dev/null +++ b/examples/find__object_t_key_type.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/find__object_t_key_type.output b/examples/find__object_t_key_type.output new file mode 100644 index 000000000..509bb42d5 --- /dev/null +++ b/examples/find__object_t_key_type.output @@ -0,0 +1,3 @@ +"two" was found: true +value at key "two": 2 +"three" was found: false diff --git a/examples/flatten.cpp b/examples/flatten.cpp new file mode 100644 index 000000000..83f3ff6c3 --- /dev/null +++ b/examples/flatten.cpp @@ -0,0 +1,32 @@ +#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'; +} diff --git a/examples/flatten.output b/examples/flatten.output new file mode 100644 index 000000000..33bd4c4b9 --- /dev/null +++ b/examples/flatten.output @@ -0,0 +1,12 @@ +{ + "/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 +} diff --git a/examples/from_bjdata.cpp b/examples/from_bjdata.cpp new file mode 100644 index 000000000..961164c29 --- /dev/null +++ b/examples/from_bjdata.cpp @@ -0,0 +1,20 @@ +#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; +} diff --git a/examples/from_bjdata.output b/examples/from_bjdata.output new file mode 100644 index 000000000..259f63bd4 --- /dev/null +++ b/examples/from_bjdata.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/examples/from_bson.cpp b/examples/from_bson.cpp new file mode 100644 index 000000000..c9d9fdfa6 --- /dev/null +++ b/examples/from_bson.cpp @@ -0,0 +1,21 @@ +#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; +} diff --git a/examples/from_bson.output b/examples/from_bson.output new file mode 100644 index 000000000..259f63bd4 --- /dev/null +++ b/examples/from_bson.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/examples/from_cbor.cpp b/examples/from_cbor.cpp new file mode 100644 index 000000000..e685329ef --- /dev/null +++ b/examples/from_cbor.cpp @@ -0,0 +1,20 @@ +#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; +} diff --git a/examples/from_cbor.output b/examples/from_cbor.output new file mode 100644 index 000000000..259f63bd4 --- /dev/null +++ b/examples/from_cbor.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/examples/from_json__default_constructible.cpp b/examples/from_json__default_constructible.cpp new file mode 100644 index 000000000..17c0551c8 --- /dev/null +++ b/examples/from_json__default_constructible.cpp @@ -0,0 +1,37 @@ +#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; +} diff --git a/examples/from_json__default_constructible.output b/examples/from_json__default_constructible.output new file mode 100644 index 000000000..b92452326 --- /dev/null +++ b/examples/from_json__default_constructible.output @@ -0,0 +1 @@ +Ned Flanders (60) lives in 744 Evergreen Terrace diff --git a/examples/from_json__non_default_constructible.cpp b/examples/from_json__non_default_constructible.cpp new file mode 100644 index 000000000..6cb86153c --- /dev/null +++ b/examples/from_json__non_default_constructible.cpp @@ -0,0 +1,53 @@ +#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; +} diff --git a/examples/from_json__non_default_constructible.output b/examples/from_json__non_default_constructible.output new file mode 100644 index 000000000..b92452326 --- /dev/null +++ b/examples/from_json__non_default_constructible.output @@ -0,0 +1 @@ +Ned Flanders (60) lives in 744 Evergreen Terrace diff --git a/examples/from_msgpack.cpp b/examples/from_msgpack.cpp new file mode 100644 index 000000000..5c2183f1e --- /dev/null +++ b/examples/from_msgpack.cpp @@ -0,0 +1,20 @@ +#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; +} diff --git a/examples/from_msgpack.output b/examples/from_msgpack.output new file mode 100644 index 000000000..259f63bd4 --- /dev/null +++ b/examples/from_msgpack.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/examples/from_ubjson.cpp b/examples/from_ubjson.cpp new file mode 100644 index 000000000..1e85e4e36 --- /dev/null +++ b/examples/from_ubjson.cpp @@ -0,0 +1,20 @@ +#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; +} diff --git a/examples/from_ubjson.output b/examples/from_ubjson.output new file mode 100644 index 000000000..259f63bd4 --- /dev/null +++ b/examples/from_ubjson.output @@ -0,0 +1,4 @@ +{ + "compact": true, + "schema": 0 +} diff --git a/examples/front.cpp b/examples/front.cpp new file mode 100644 index 000000000..a0f630689 --- /dev/null +++ b/examples/front.cpp @@ -0,0 +1,29 @@ +#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'; +} diff --git a/examples/front.output b/examples/front.output new file mode 100644 index 000000000..6301db533 --- /dev/null +++ b/examples/front.output @@ -0,0 +1,6 @@ +true +17 +23.42 +1 +1 +"Hello, world" diff --git a/examples/get__PointerType.cpp b/examples/get__PointerType.cpp new file mode 100644 index 000000000..2f32ed7af --- /dev/null +++ b/examples/get__PointerType.cpp @@ -0,0 +1,21 @@ +#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'; +} diff --git a/examples/get__PointerType.output b/examples/get__PointerType.output new file mode 100644 index 000000000..a15dd774e --- /dev/null +++ b/examples/get__PointerType.output @@ -0,0 +1,2 @@ +17 17 17 17 +true diff --git a/examples/get__ValueType_const.cpp b/examples/get__ValueType_const.cpp new file mode 100644 index 000000000..7a703aaeb --- /dev/null +++ b/examples/get__ValueType_const.cpp @@ -0,0 +1,50 @@ +#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'; + } +} diff --git a/examples/get__ValueType_const.output b/examples/get__ValueType_const.output new file mode 100644 index 000000000..5cd9cd3aa --- /dev/null +++ b/examples/get__ValueType_const.output @@ -0,0 +1,11 @@ +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] diff --git a/examples/get_allocator.cpp b/examples/get_allocator.cpp new file mode 100644 index 000000000..35079a10c --- /dev/null +++ b/examples/get_allocator.cpp @@ -0,0 +1,18 @@ +#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); +} diff --git a/examples/get_allocator.output b/examples/get_allocator.output new file mode 100644 index 000000000..8effb3e8c --- /dev/null +++ b/examples/get_allocator.output @@ -0,0 +1 @@ +"Hello, world!" diff --git a/examples/get_binary.cpp b/examples/get_binary.cpp new file mode 100644 index 000000000..617ce6096 --- /dev/null +++ b/examples/get_binary.cpp @@ -0,0 +1,16 @@ +#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; +} diff --git a/examples/get_binary.output b/examples/get_binary.output new file mode 100644 index 000000000..74b05d23f --- /dev/null +++ b/examples/get_binary.output @@ -0,0 +1 @@ +type: binary, subtype: 42 diff --git a/examples/get_ptr.cpp b/examples/get_ptr.cpp new file mode 100644 index 000000000..564ce0f4e --- /dev/null +++ b/examples/get_ptr.cpp @@ -0,0 +1,21 @@ +#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'; +} diff --git a/examples/get_ptr.output b/examples/get_ptr.output new file mode 100644 index 000000000..a15dd774e --- /dev/null +++ b/examples/get_ptr.output @@ -0,0 +1,2 @@ +17 17 17 17 +true diff --git a/examples/get_ref.cpp b/examples/get_ref.cpp new file mode 100644 index 000000000..ab25946bb --- /dev/null +++ b/examples/get_ref.cpp @@ -0,0 +1,27 @@ +#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 (json::type_error& ex) + { + std::cout << ex.what() << '\n'; + } +} diff --git a/examples/get_ref.output b/examples/get_ref.output new file mode 100644 index 000000000..3811afa2f --- /dev/null +++ b/examples/get_ref.output @@ -0,0 +1,2 @@ +17 17 +[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number diff --git a/examples/get_to.cpp b/examples/get_to.cpp new file mode 100644 index 000000000..4705b172f --- /dev/null +++ b/examples/get_to.cpp @@ -0,0 +1,60 @@ +#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'; + } +} diff --git a/examples/get_to.output b/examples/get_to.output new file mode 100644 index 000000000..5cd9cd3aa --- /dev/null +++ b/examples/get_to.output @@ -0,0 +1,11 @@ +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] diff --git a/examples/insert.cpp b/examples/insert.cpp new file mode 100644 index 000000000..4ee609876 --- /dev/null +++ b/examples/insert.cpp @@ -0,0 +1,17 @@ +#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'; +} diff --git a/examples/insert.output b/examples/insert.output new file mode 100644 index 000000000..ed5cab1d0 --- /dev/null +++ b/examples/insert.output @@ -0,0 +1,2 @@ +10 +[1,2,10,3,4] diff --git a/examples/insert__count.cpp b/examples/insert__count.cpp new file mode 100644 index 000000000..ce33b93e4 --- /dev/null +++ b/examples/insert__count.cpp @@ -0,0 +1,17 @@ +#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'; +} diff --git a/examples/insert__count.output b/examples/insert__count.output new file mode 100644 index 000000000..294685ac4 --- /dev/null +++ b/examples/insert__count.output @@ -0,0 +1,2 @@ +7 +[1,2,7,7,7,7,7,7,7,3,4] diff --git a/examples/insert__ilist.cpp b/examples/insert__ilist.cpp new file mode 100644 index 000000000..a20766a14 --- /dev/null +++ b/examples/insert__ilist.cpp @@ -0,0 +1,17 @@ +#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'; +} diff --git a/examples/insert__ilist.output b/examples/insert__ilist.output new file mode 100644 index 000000000..b2fc7eeb9 --- /dev/null +++ b/examples/insert__ilist.output @@ -0,0 +1,2 @@ +7 +[1,2,3,4,7,8,9] diff --git a/examples/insert__range.cpp b/examples/insert__range.cpp new file mode 100644 index 000000000..92fe63b0d --- /dev/null +++ b/examples/insert__range.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/insert__range.output b/examples/insert__range.output new file mode 100644 index 000000000..d50e9f63a --- /dev/null +++ b/examples/insert__range.output @@ -0,0 +1,2 @@ +"one" +[1,2,3,4,"one","two","three","four"] diff --git a/examples/insert__range_object.cpp b/examples/insert__range_object.cpp new file mode 100644 index 000000000..97373d3b4 --- /dev/null +++ b/examples/insert__range_object.cpp @@ -0,0 +1,21 @@ +#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'; +} diff --git a/examples/insert__range_object.output b/examples/insert__range_object.output new file mode 100644 index 000000000..a5985158a --- /dev/null +++ b/examples/insert__range_object.output @@ -0,0 +1,3 @@ +{"one":"eins","two":"zwei"} +{"eleven":"elf","seventeen":"siebzehn"} +{"eleven":"elf","one":"eins","seventeen":"siebzehn","two":"zwei"} diff --git a/examples/invalid_iterator.cpp b/examples/invalid_iterator.cpp new file mode 100644 index 000000000..5d3e622e6 --- /dev/null +++ b/examples/invalid_iterator.cpp @@ -0,0 +1,21 @@ +#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 (json::invalid_iterator& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/examples/invalid_iterator.output b/examples/invalid_iterator.output new file mode 100644 index 000000000..8668c16d1 --- /dev/null +++ b/examples/invalid_iterator.output @@ -0,0 +1,2 @@ +message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators +exception id: 207 diff --git a/examples/is_array.cpp b/examples/is_array.cpp new file mode 100644 index 000000000..8ecc45035 --- /dev/null +++ b/examples/is_array.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_array.output b/examples/is_array.output new file mode 100644 index 000000000..7b7ef3f19 --- /dev/null +++ b/examples/is_array.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +true +false +false diff --git a/examples/is_binary.cpp b/examples/is_binary.cpp new file mode 100644 index 000000000..d7f049ec4 --- /dev/null +++ b/examples/is_binary.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_binary.output b/examples/is_binary.output new file mode 100644 index 000000000..505e76e4f --- /dev/null +++ b/examples/is_binary.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +false +false +true diff --git a/examples/is_boolean.cpp b/examples/is_boolean.cpp new file mode 100644 index 000000000..0b7981955 --- /dev/null +++ b/examples/is_boolean.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_boolean.output b/examples/is_boolean.output new file mode 100644 index 000000000..eace89d22 --- /dev/null +++ b/examples/is_boolean.output @@ -0,0 +1,9 @@ +false +true +false +false +false +false +false +false +false diff --git a/examples/is_discarded.cpp b/examples/is_discarded.cpp new file mode 100644 index 000000000..09016655e --- /dev/null +++ b/examples/is_discarded.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_discarded.output b/examples/is_discarded.output new file mode 100644 index 000000000..14718f64e --- /dev/null +++ b/examples/is_discarded.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +false +false +false diff --git a/examples/is_null.cpp b/examples/is_null.cpp new file mode 100644 index 000000000..8a8433260 --- /dev/null +++ b/examples/is_null.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_null.output b/examples/is_null.output new file mode 100644 index 000000000..42bbee2a7 --- /dev/null +++ b/examples/is_null.output @@ -0,0 +1,9 @@ +true +false +false +false +false +false +false +false +false diff --git a/examples/is_number.cpp b/examples/is_number.cpp new file mode 100644 index 000000000..f107a048a --- /dev/null +++ b/examples/is_number.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_number.output b/examples/is_number.output new file mode 100644 index 000000000..53ef340bb --- /dev/null +++ b/examples/is_number.output @@ -0,0 +1,9 @@ +false +false +true +true +true +false +false +false +false diff --git a/examples/is_number_float.cpp b/examples/is_number_float.cpp new file mode 100644 index 000000000..bba2b446f --- /dev/null +++ b/examples/is_number_float.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_number_float.output b/examples/is_number_float.output new file mode 100644 index 000000000..0e64601ab --- /dev/null +++ b/examples/is_number_float.output @@ -0,0 +1,9 @@ +false +false +false +false +true +false +false +false +false diff --git a/examples/is_number_integer.cpp b/examples/is_number_integer.cpp new file mode 100644 index 000000000..8d6a5ae16 --- /dev/null +++ b/examples/is_number_integer.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_number_integer.output b/examples/is_number_integer.output new file mode 100644 index 000000000..c1df310f4 --- /dev/null +++ b/examples/is_number_integer.output @@ -0,0 +1,9 @@ +false +false +true +true +false +false +false +false +false diff --git a/examples/is_number_unsigned.cpp b/examples/is_number_unsigned.cpp new file mode 100644 index 000000000..b52ac6b31 --- /dev/null +++ b/examples/is_number_unsigned.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_number_unsigned.output b/examples/is_number_unsigned.output new file mode 100644 index 000000000..e6059d48f --- /dev/null +++ b/examples/is_number_unsigned.output @@ -0,0 +1,9 @@ +false +false +false +true +false +false +false +false +false diff --git a/examples/is_object.cpp b/examples/is_object.cpp new file mode 100644 index 000000000..a0216fd21 --- /dev/null +++ b/examples/is_object.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_object.output b/examples/is_object.output new file mode 100644 index 000000000..d9a429f8f --- /dev/null +++ b/examples/is_object.output @@ -0,0 +1,9 @@ +false +false +false +false +false +true +false +false +false diff --git a/examples/is_primitive.cpp b/examples/is_primitive.cpp new file mode 100644 index 000000000..af3968e83 --- /dev/null +++ b/examples/is_primitive.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_primitive.output b/examples/is_primitive.output new file mode 100644 index 000000000..77af24c00 --- /dev/null +++ b/examples/is_primitive.output @@ -0,0 +1,9 @@ +true +true +true +true +true +false +false +true +true diff --git a/examples/is_string.cpp b/examples/is_string.cpp new file mode 100644 index 000000000..c89f550b0 --- /dev/null +++ b/examples/is_string.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_string.output b/examples/is_string.output new file mode 100644 index 000000000..6446f1878 --- /dev/null +++ b/examples/is_string.output @@ -0,0 +1,9 @@ +false +false +false +false +false +false +false +true +false diff --git a/examples/is_structured.cpp b/examples/is_structured.cpp new file mode 100644 index 000000000..41947b1be --- /dev/null +++ b/examples/is_structured.cpp @@ -0,0 +1,30 @@ +#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'; +} diff --git a/examples/is_structured.output b/examples/is_structured.output new file mode 100644 index 000000000..625c124b5 --- /dev/null +++ b/examples/is_structured.output @@ -0,0 +1,9 @@ +false +false +false +false +false +true +true +false +false diff --git a/examples/items.cpp b/examples/items.cpp new file mode 100644 index 000000000..9cd2b51b1 --- /dev/null +++ b/examples/items.cpp @@ -0,0 +1,23 @@ +#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'; + } +} diff --git a/examples/items.output b/examples/items.output new file mode 100644 index 000000000..89b09f524 --- /dev/null +++ b/examples/items.output @@ -0,0 +1,7 @@ +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 diff --git a/examples/json_base_class_t.cpp b/examples/json_base_class_t.cpp new file mode 100644 index 000000000..d993522a7 --- /dev/null +++ b/examples/json_base_class_t.cpp @@ -0,0 +1,88 @@ +#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'; + }); +} diff --git a/examples/json_base_class_t.output b/examples/json_base_class_t.output new file mode 100644 index 000000000..83ce1f693 --- /dev/null +++ b/examples/json_base_class_t.output @@ -0,0 +1,4 @@ +/ - metadata = 42 -> {"null":null,"object":{"uint":1}} +/null - metadata = 42 -> null +/object - metadata = 21 -> {"uint":1} +/object/uint - metadata = 42 -> 1 diff --git a/examples/json_lines.cpp b/examples/json_lines.cpp new file mode 100644 index 000000000..233c81a4a --- /dev/null +++ b/examples/json_lines.cpp @@ -0,0 +1,22 @@ +#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; + } +} diff --git a/examples/json_lines.output b/examples/json_lines.output new file mode 100644 index 000000000..1b4122480 --- /dev/null +++ b/examples/json_lines.output @@ -0,0 +1,4 @@ +{"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♣"]]} diff --git a/examples/json_pointer.cpp b/examples/json_pointer.cpp new file mode 100644 index 000000000..75b971758 --- /dev/null +++ b/examples/json_pointer.cpp @@ -0,0 +1,47 @@ +#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 (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 (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 (json::parse_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/json_pointer.output b/examples/json_pointer.output new file mode 100644 index 000000000..9e027d6dc --- /dev/null +++ b/examples/json_pointer.output @@ -0,0 +1,3 @@ +[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' diff --git a/examples/json_pointer__back.cpp b/examples/json_pointer__back.cpp new file mode 100644 index 000000000..dd3b210bf --- /dev/null +++ b/examples/json_pointer__back.cpp @@ -0,0 +1,15 @@ +#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; +} diff --git a/examples/json_pointer__back.output b/examples/json_pointer__back.output new file mode 100644 index 000000000..a89357b49 --- /dev/null +++ b/examples/json_pointer__back.output @@ -0,0 +1,2 @@ +last reference token of "/foo" is "foo" +last reference token of "/foo/0" is "0" diff --git a/examples/json_pointer__empty.cpp b/examples/json_pointer__empty.cpp new file mode 100644 index 000000000..57257e8b1 --- /dev/null +++ b/examples/json_pointer__empty.cpp @@ -0,0 +1,20 @@ +#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; +} diff --git a/examples/json_pointer__empty.output b/examples/json_pointer__empty.output new file mode 100644 index 000000000..a7ee49c17 --- /dev/null +++ b/examples/json_pointer__empty.output @@ -0,0 +1,4 @@ +"": true +"": true +"/foo": false +"/foo/0": false diff --git a/examples/json_pointer__operator__equal.cpp b/examples/json_pointer__operator__equal.cpp new file mode 100644 index 000000000..dce6df03c --- /dev/null +++ b/examples/json_pointer__operator__equal.cpp @@ -0,0 +1,19 @@ +#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; +} diff --git a/examples/json_pointer__operator__equal.output b/examples/json_pointer__operator__equal.output new file mode 100644 index 000000000..9a7612580 --- /dev/null +++ b/examples/json_pointer__operator__equal.output @@ -0,0 +1,4 @@ +"" == "": true +"" == "": true +"" == "/foo": false +"/foo" == "/foo": true diff --git a/examples/json_pointer__operator__equal_stringtype.cpp b/examples/json_pointer__operator__equal_stringtype.cpp new file mode 100644 index 000000000..af8ec5a29 --- /dev/null +++ b/examples/json_pointer__operator__equal_stringtype.cpp @@ -0,0 +1,33 @@ +#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; + } +} diff --git a/examples/json_pointer__operator__equal_stringtype.output b/examples/json_pointer__operator__equal_stringtype.output new file mode 100644 index 000000000..7fb299d3d --- /dev/null +++ b/examples/json_pointer__operator__equal_stringtype.output @@ -0,0 +1,4 @@ +"" == "": 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' diff --git a/examples/json_pointer__operator__notequal.cpp b/examples/json_pointer__operator__notequal.cpp new file mode 100644 index 000000000..9bbdd5310 --- /dev/null +++ b/examples/json_pointer__operator__notequal.cpp @@ -0,0 +1,19 @@ +#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; +} diff --git a/examples/json_pointer__operator__notequal.output b/examples/json_pointer__operator__notequal.output new file mode 100644 index 000000000..de891f0c6 --- /dev/null +++ b/examples/json_pointer__operator__notequal.output @@ -0,0 +1,4 @@ +"" != "": false +"" != "": false +"" != "/foo": true +"/foo" != "/foo": false diff --git a/examples/json_pointer__operator__notequal_stringtype.cpp b/examples/json_pointer__operator__notequal_stringtype.cpp new file mode 100644 index 000000000..b9b898728 --- /dev/null +++ b/examples/json_pointer__operator__notequal_stringtype.cpp @@ -0,0 +1,32 @@ +#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; + } +} diff --git a/examples/json_pointer__operator__notequal_stringtype.output b/examples/json_pointer__operator__notequal_stringtype.output new file mode 100644 index 000000000..61331b752 --- /dev/null +++ b/examples/json_pointer__operator__notequal_stringtype.output @@ -0,0 +1,4 @@ +"" != "": 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' diff --git a/examples/json_pointer__operator_add.cpp b/examples/json_pointer__operator_add.cpp new file mode 100644 index 000000000..14bd74561 --- /dev/null +++ b/examples/json_pointer__operator_add.cpp @@ -0,0 +1,23 @@ +#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; +} diff --git a/examples/json_pointer__operator_add.output b/examples/json_pointer__operator_add.output new file mode 100644 index 000000000..ae13afe27 --- /dev/null +++ b/examples/json_pointer__operator_add.output @@ -0,0 +1,4 @@ +"/foo" +"/foo/bar/baz" +"/foo/bar/baz/fob" +"/foo/bar/baz/fob/42" diff --git a/examples/json_pointer__operator_add_binary.cpp b/examples/json_pointer__operator_add_binary.cpp new file mode 100644 index 000000000..d26a0d171 --- /dev/null +++ b/examples/json_pointer__operator_add_binary.cpp @@ -0,0 +1,19 @@ +#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; +} diff --git a/examples/json_pointer__operator_add_binary.output b/examples/json_pointer__operator_add_binary.output new file mode 100644 index 000000000..7536042c0 --- /dev/null +++ b/examples/json_pointer__operator_add_binary.output @@ -0,0 +1,3 @@ +"/foo/bar/baz" +"/foo/fob" +"/foo/42" diff --git a/examples/json_pointer__operator_string_t.cpp b/examples/json_pointer__operator_string_t.cpp new file mode 100644 index 000000000..56f213020 --- /dev/null +++ b/examples/json_pointer__operator_string_t.cpp @@ -0,0 +1,19 @@ +#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; +} diff --git a/examples/json_pointer__operator_string_t.output b/examples/json_pointer__operator_string_t.output new file mode 100644 index 000000000..ec6aba2c2 --- /dev/null +++ b/examples/json_pointer__operator_string_t.output @@ -0,0 +1,2 @@ +/foo/0 +/a~1b diff --git a/examples/json_pointer__parent_pointer.cpp b/examples/json_pointer__parent_pointer.cpp new file mode 100644 index 000000000..ef9df4534 --- /dev/null +++ b/examples/json_pointer__parent_pointer.cpp @@ -0,0 +1,18 @@ +#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; +} diff --git a/examples/json_pointer__parent_pointer.output b/examples/json_pointer__parent_pointer.output new file mode 100644 index 000000000..4cc6f3f1b --- /dev/null +++ b/examples/json_pointer__parent_pointer.output @@ -0,0 +1,3 @@ +parent of "" is "" +parent of "/foo" is "" +parent of "/foo/0" is "/foo" diff --git a/examples/json_pointer__pop_back.cpp b/examples/json_pointer__pop_back.cpp new file mode 100644 index 000000000..fd077b7e9 --- /dev/null +++ b/examples/json_pointer__pop_back.cpp @@ -0,0 +1,21 @@ +#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"; +} diff --git a/examples/json_pointer__pop_back.output b/examples/json_pointer__pop_back.output new file mode 100644 index 000000000..b0468dc51 --- /dev/null +++ b/examples/json_pointer__pop_back.output @@ -0,0 +1,4 @@ +"/foo/bar/baz" +"/foo/bar" +"/foo" +"" diff --git a/examples/json_pointer__push_back.cpp b/examples/json_pointer__push_back.cpp new file mode 100644 index 000000000..e6b59a125 --- /dev/null +++ b/examples/json_pointer__push_back.cpp @@ -0,0 +1,21 @@ +#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"; +} diff --git a/examples/json_pointer__push_back.output b/examples/json_pointer__push_back.output new file mode 100644 index 000000000..92c019cd3 --- /dev/null +++ b/examples/json_pointer__push_back.output @@ -0,0 +1,4 @@ +"" +"/foo" +"/foo/0" +"/foo/0/bar" diff --git a/examples/json_pointer__string_t.cpp b/examples/json_pointer__string_t.cpp new file mode 100644 index 000000000..fbe0f179e --- /dev/null +++ b/examples/json_pointer__string_t.cpp @@ -0,0 +1,13 @@ +#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; +} diff --git a/examples/json_pointer__string_t.output b/examples/json_pointer__string_t.output new file mode 100644 index 000000000..d87113724 --- /dev/null +++ b/examples/json_pointer__string_t.output @@ -0,0 +1,2 @@ +This is a string. +true diff --git a/examples/json_pointer__to_string.cpp b/examples/json_pointer__to_string.cpp new file mode 100644 index 000000000..31d35a724 --- /dev/null +++ b/examples/json_pointer__to_string.cpp @@ -0,0 +1,34 @@ +#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; +} diff --git a/examples/json_pointer__to_string.output b/examples/json_pointer__to_string.output new file mode 100644 index 000000000..3c441357e --- /dev/null +++ b/examples/json_pointer__to_string.output @@ -0,0 +1,12 @@ +"" +"/foo" +"/foo/0" +"/" +"/a~1b" +"/c%d" +"/e^f" +"/g|h" +"/i\j" +"/k"l" +"/ " +"/m~0n" diff --git a/examples/max_size.cpp b/examples/max_size.cpp new file mode 100644 index 000000000..c2ffc5468 --- /dev/null +++ b/examples/max_size.cpp @@ -0,0 +1,25 @@ +#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'; +} diff --git a/examples/max_size.output b/examples/max_size.output new file mode 100644 index 000000000..b8dcb4d0c --- /dev/null +++ b/examples/max_size.output @@ -0,0 +1,7 @@ +0 +1 +1 +1 +115292150460684697 +576460752303423487 +1 diff --git a/examples/merge_patch.cpp b/examples/merge_patch.cpp new file mode 100644 index 000000000..f3fee1ed1 --- /dev/null +++ b/examples/merge_patch.cpp @@ -0,0 +1,41 @@ +#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; +} diff --git a/examples/merge_patch.output b/examples/merge_patch.output new file mode 100644 index 000000000..96adb7b3b --- /dev/null +++ b/examples/merge_patch.output @@ -0,0 +1,11 @@ +{ + "author": { + "givenName": "John" + }, + "content": "This will be unchanged", + "phoneNumber": "+01-123-456-7890", + "tags": [ + "example" + ], + "title": "Hello!" +} diff --git a/examples/meta.cpp b/examples/meta.cpp new file mode 100644 index 000000000..a051575ba --- /dev/null +++ b/examples/meta.cpp @@ -0,0 +1,11 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + // call meta() + std::cout << std::setw(4) << json::meta() << '\n'; +} diff --git a/examples/meta.output b/examples/meta.output new file mode 100644 index 000000000..9ceb5e201 --- /dev/null +++ b/examples/meta.output @@ -0,0 +1,17 @@ +{ + "compiler": { + "c++": "201103", + "family": "gcc", + "version": "12.1.0" + }, + "copyright": "(C) 2013-2022 Niels Lohmann", + "name": "JSON for Modern C++", + "platform": "apple", + "url": "https://github.com/nlohmann/json", + "version": { + "major": 3, + "minor": 11, + "patch": 2, + "string": "3.11.2" + } +} diff --git a/examples/nlohmann_define_type_intrusive_explicit.cpp b/examples/nlohmann_define_type_intrusive_explicit.cpp new file mode 100644 index 000000000..7d2ba8aa1 --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_explicit.cpp @@ -0,0 +1,60 @@ +#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_) + {} + + friend void to_json(nlohmann::json& 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; + } + + friend void from_json(const nlohmann::json& 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 (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/examples/nlohmann_define_type_intrusive_explicit.output b/examples/nlohmann_define_type_intrusive_explicit.output new file mode 100644 index 000000000..37f4eb414 --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/examples/nlohmann_define_type_intrusive_macro.cpp b/examples/nlohmann_define_type_intrusive_macro.cpp new file mode 100644 index 000000000..2977cd456 --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_macro.cpp @@ -0,0 +1,48 @@ +#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 (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/examples/nlohmann_define_type_intrusive_macro.output b/examples/nlohmann_define_type_intrusive_macro.output new file mode 100644 index 000000000..37f4eb414 --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp b/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp new file mode 100644 index 000000000..7400c47a8 --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_with_default_explicit.cpp @@ -0,0 +1,55 @@ +#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_) + {} + + friend void to_json(nlohmann::json& 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; + } + + friend void from_json(const nlohmann::json& 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; +} diff --git a/examples/nlohmann_define_type_intrusive_with_default_explicit.output b/examples/nlohmann_define_type_intrusive_with_default_explicit.output new file mode 100644 index 000000000..1a255f65c --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_with_default_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/examples/nlohmann_define_type_intrusive_with_default_macro.cpp b/examples/nlohmann_define_type_intrusive_with_default_macro.cpp new file mode 100644 index 000000000..851a3582f --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_with_default_macro.cpp @@ -0,0 +1,42 @@ +#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; +} diff --git a/examples/nlohmann_define_type_intrusive_with_default_macro.output b/examples/nlohmann_define_type_intrusive_with_default_macro.output new file mode 100644 index 000000000..1a255f65c --- /dev/null +++ b/examples/nlohmann_define_type_intrusive_with_default_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/examples/nlohmann_define_type_non_intrusive_explicit.cpp b/examples/nlohmann_define_type_non_intrusive_explicit.cpp new file mode 100644 index 000000000..b71613d4f --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_explicit.cpp @@ -0,0 +1,53 @@ +#include +#include + +using json = nlohmann::json; +using namespace nlohmann::literals; + +namespace ns +{ +struct person +{ + std::string name; + std::string address; + int age; +}; + +void to_json(nlohmann::json& 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; +} + +void from_json(const nlohmann::json& 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 (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/examples/nlohmann_define_type_non_intrusive_explicit.output b/examples/nlohmann_define_type_non_intrusive_explicit.output new file mode 100644 index 000000000..37f4eb414 --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/examples/nlohmann_define_type_non_intrusive_macro.cpp b/examples/nlohmann_define_type_non_intrusive_macro.cpp new file mode 100644 index 000000000..be11a4576 --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_macro.cpp @@ -0,0 +1,41 @@ +#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 (json::exception& e) + { + std::cout << "deserialization failed: " << e.what() << std::endl; + } +} diff --git a/examples/nlohmann_define_type_non_intrusive_macro.output b/examples/nlohmann_define_type_non_intrusive_macro.output new file mode 100644 index 000000000..37f4eb414 --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +deserialization failed: [json.exception.out_of_range.403] key 'age' not found diff --git a/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp b/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp new file mode 100644 index 000000000..6b538d18d --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_with_default_explicit.cpp @@ -0,0 +1,53 @@ +#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_) + {} +}; + +void to_json(nlohmann::json& 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; +} + +void from_json(const nlohmann::json& 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; +} diff --git a/examples/nlohmann_define_type_non_intrusive_with_default_explicit.output b/examples/nlohmann_define_type_non_intrusive_with_default_explicit.output new file mode 100644 index 000000000..1a255f65c --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_with_default_explicit.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp b/examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp new file mode 100644 index 000000000..aa9bc53b4 --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_with_default_macro.cpp @@ -0,0 +1,40 @@ +#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; +} diff --git a/examples/nlohmann_define_type_non_intrusive_with_default_macro.output b/examples/nlohmann_define_type_non_intrusive_with_default_macro.output new file mode 100644 index 000000000..1a255f65c --- /dev/null +++ b/examples/nlohmann_define_type_non_intrusive_with_default_macro.output @@ -0,0 +1,2 @@ +serialization: {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} +roundtrip: {"address":"742 Evergreen Terrace","age":-1,"name":"Maggie Simpson"} diff --git a/examples/nlohmann_json_namespace.cpp b/examples/nlohmann_json_namespace.cpp new file mode 100644 index 000000000..4bad91f4b --- /dev/null +++ b/examples/nlohmann_json_namespace.cpp @@ -0,0 +1,14 @@ +#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; +} diff --git a/examples/nlohmann_json_namespace.output b/examples/nlohmann_json_namespace.output new file mode 100644 index 000000000..1a1df5a3d --- /dev/null +++ b/examples/nlohmann_json_namespace.output @@ -0,0 +1 @@ +nlohmann::json_abi_v3_11_2 diff --git a/examples/nlohmann_json_namespace_begin.c++17.cpp b/examples/nlohmann_json_namespace_begin.c++17.cpp new file mode 100644 index 000000000..9385d593d --- /dev/null +++ b/examples/nlohmann_json_namespace_begin.c++17.cpp @@ -0,0 +1,33 @@ +#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; +} diff --git a/examples/nlohmann_json_namespace_begin.c++17.output b/examples/nlohmann_json_namespace_begin.c++17.output new file mode 100644 index 000000000..b29d3b93c --- /dev/null +++ b/examples/nlohmann_json_namespace_begin.c++17.output @@ -0,0 +1 @@ +[1,null] diff --git a/examples/nlohmann_json_namespace_no_version.cpp b/examples/nlohmann_json_namespace_no_version.cpp new file mode 100644 index 000000000..97948dd7e --- /dev/null +++ b/examples/nlohmann_json_namespace_no_version.cpp @@ -0,0 +1,13 @@ +#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; +} diff --git a/examples/nlohmann_json_namespace_no_version.output b/examples/nlohmann_json_namespace_no_version.output new file mode 100644 index 000000000..1c8f3132b --- /dev/null +++ b/examples/nlohmann_json_namespace_no_version.output @@ -0,0 +1 @@ +nlohmann::json_abi diff --git a/examples/nlohmann_json_serialize_enum.cpp b/examples/nlohmann_json_serialize_enum.cpp new file mode 100644 index 000000000..f9e472c64 --- /dev/null +++ b/examples/nlohmann_json_serialize_enum.cpp @@ -0,0 +1,59 @@ +#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; +} diff --git a/examples/nlohmann_json_serialize_enum.output b/examples/nlohmann_json_serialize_enum.output new file mode 100644 index 000000000..f512563dd --- /dev/null +++ b/examples/nlohmann_json_serialize_enum.output @@ -0,0 +1,3 @@ +ns::TS_STOPPED -> "stopped", ns::Color::red -> "red" +"running" -> 1, "blue" -> 2 +3.14 -> -1, 3.14 -> 3 diff --git a/examples/nlohmann_json_serialize_enum_2.cpp b/examples/nlohmann_json_serialize_enum_2.cpp new file mode 100644 index 000000000..fd27226ca --- /dev/null +++ b/examples/nlohmann_json_serialize_enum_2.cpp @@ -0,0 +1,33 @@ +#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; +} diff --git a/examples/nlohmann_json_serialize_enum_2.output b/examples/nlohmann_json_serialize_enum_2.output new file mode 100644 index 000000000..5dec31b4a --- /dev/null +++ b/examples/nlohmann_json_serialize_enum_2.output @@ -0,0 +1,3 @@ +0 -> "red" +"rot" -> 0 +"red" -> 0 diff --git a/examples/nlohmann_json_version.cpp b/examples/nlohmann_json_version.cpp new file mode 100644 index 000000000..ca5f53728 --- /dev/null +++ b/examples/nlohmann_json_version.cpp @@ -0,0 +1,12 @@ +#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; +} diff --git a/examples/nlohmann_json_version.output b/examples/nlohmann_json_version.output new file mode 100644 index 000000000..043b9b234 --- /dev/null +++ b/examples/nlohmann_json_version.output @@ -0,0 +1 @@ +JSON for Modern C++ version 3.11.2 diff --git a/examples/number_float_t.cpp b/examples/number_float_t.cpp new file mode 100644 index 000000000..21211dc51 --- /dev/null +++ b/examples/number_float_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/examples/number_float_t.output b/examples/number_float_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/number_float_t.output @@ -0,0 +1 @@ +true diff --git a/examples/number_integer_t.cpp b/examples/number_integer_t.cpp new file mode 100644 index 000000000..75ee57b63 --- /dev/null +++ b/examples/number_integer_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/examples/number_integer_t.output b/examples/number_integer_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/number_integer_t.output @@ -0,0 +1 @@ +true diff --git a/examples/number_unsigned_t.cpp b/examples/number_unsigned_t.cpp new file mode 100644 index 000000000..ff3b86df8 --- /dev/null +++ b/examples/number_unsigned_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/examples/number_unsigned_t.output b/examples/number_unsigned_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/number_unsigned_t.output @@ -0,0 +1 @@ +true diff --git a/examples/object.cpp b/examples/object.cpp new file mode 100644 index 000000000..733b89b53 --- /dev/null +++ b/examples/object.cpp @@ -0,0 +1,28 @@ +#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 (json::type_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/object.output b/examples/object.output new file mode 100644 index 000000000..1a1d8140e --- /dev/null +++ b/examples/object.output @@ -0,0 +1,4 @@ +{} +{} +{"one":1,"two":2} +[json.exception.type_error.301] cannot create object from initializer list diff --git a/examples/object_comparator_t.cpp b/examples/object_comparator_t.cpp new file mode 100644 index 000000000..6b82c7ca6 --- /dev/null +++ b/examples/object_comparator_t.cpp @@ -0,0 +1,11 @@ +#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; +} diff --git a/examples/object_comparator_t.output b/examples/object_comparator_t.output new file mode 100644 index 000000000..63620edb4 --- /dev/null +++ b/examples/object_comparator_t.output @@ -0,0 +1,2 @@ +json::object_comparator_t("one", "two") = true +json::object_comparator_t("three", "four") = false diff --git a/examples/object_t.cpp b/examples/object_t.cpp new file mode 100644 index 000000000..85cfa3e33 --- /dev/null +++ b/examples/object_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same, json::object_t>::value << std::endl; +} diff --git a/examples/object_t.output b/examples/object_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/object_t.output @@ -0,0 +1 @@ +true diff --git a/examples/operator__ValueType.cpp b/examples/operator__ValueType.cpp new file mode 100644 index 000000000..66fcf310e --- /dev/null +++ b/examples/operator__ValueType.cpp @@ -0,0 +1,60 @@ +#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 (json::type_error& e) + { + std::cout << e.what() << '\n'; + } +} diff --git a/examples/operator__ValueType.output b/examples/operator__ValueType.output new file mode 100644 index 000000000..a3bd9fff4 --- /dev/null +++ b/examples/operator__ValueType.output @@ -0,0 +1,12 @@ +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 diff --git a/examples/operator__equal.cpp b/examples/operator__equal.cpp new file mode 100644 index 000000000..1426f489a --- /dev/null +++ b/examples/operator__equal.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/operator__equal.output b/examples/operator__equal.output new file mode 100644 index 000000000..780673556 --- /dev/null +++ b/examples/operator__equal.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] false +{"A":"a","B":"b"} == {"A":"a","B":"b"} true +17 == 17.0 true +"foo" == "bar" false diff --git a/examples/operator__equal__nullptr_t.cpp b/examples/operator__equal__nullptr_t.cpp new file mode 100644 index 000000000..dbb210372 --- /dev/null +++ b/examples/operator__equal__nullptr_t.cpp @@ -0,0 +1,22 @@ +#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'; +} diff --git a/examples/operator__equal__nullptr_t.output b/examples/operator__equal__nullptr_t.output new file mode 100644 index 000000000..b7128e13d --- /dev/null +++ b/examples/operator__equal__nullptr_t.output @@ -0,0 +1,5 @@ +[1,2,3] == nullptr false +{"A":"a","B":"b"} == nullptr false +17 == nullptr false +"foo" == nullptr false +null == nullptr true diff --git a/examples/operator__equal__specializations.cpp b/examples/operator__equal__specializations.cpp new file mode 100644 index 000000000..97d5ecead --- /dev/null +++ b/examples/operator__equal__specializations.cpp @@ -0,0 +1,16 @@ +#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; +} diff --git a/examples/operator__equal__specializations.output b/examples/operator__equal__specializations.output new file mode 100644 index 000000000..da29283aa --- /dev/null +++ b/examples/operator__equal__specializations.output @@ -0,0 +1,2 @@ +true +false diff --git a/examples/operator__greater.cpp b/examples/operator__greater.cpp new file mode 100644 index 000000000..65bb9c049 --- /dev/null +++ b/examples/operator__greater.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/operator__greater.output b/examples/operator__greater.output new file mode 100644 index 000000000..910c48e3e --- /dev/null +++ b/examples/operator__greater.output @@ -0,0 +1,4 @@ +[1,2,3] > [1,2,4] false +{"A":"a","B":"b"} > {"A":"a","B":"b"} false +17 > 17.0000000000001 false +"foo" > "bar" true diff --git a/examples/operator__greaterequal.cpp b/examples/operator__greaterequal.cpp new file mode 100644 index 000000000..f8659ee07 --- /dev/null +++ b/examples/operator__greaterequal.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/operator__greaterequal.output b/examples/operator__greaterequal.output new file mode 100644 index 000000000..c7b91514e --- /dev/null +++ b/examples/operator__greaterequal.output @@ -0,0 +1,4 @@ +[1,2,3] >= [1,2,4] false +{"A":"a","B":"b"} >= {"A":"a","B":"b"} true +17 >= 17.0000000000001 false +"foo" >= "bar" true diff --git a/examples/operator__less.cpp b/examples/operator__less.cpp new file mode 100644 index 000000000..64209a22a --- /dev/null +++ b/examples/operator__less.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/operator__less.output b/examples/operator__less.output new file mode 100644 index 000000000..abbbc455e --- /dev/null +++ b/examples/operator__less.output @@ -0,0 +1,4 @@ +[1,2,3] == [1,2,4] true +{"A":"a","B":"b"} == {"A":"a","B":"b"} false +17 == 17.0000000000001 true +"foo" == "bar" false diff --git a/examples/operator__lessequal.cpp b/examples/operator__lessequal.cpp new file mode 100644 index 000000000..543b9543f --- /dev/null +++ b/examples/operator__lessequal.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/operator__lessequal.output b/examples/operator__lessequal.output new file mode 100644 index 000000000..f7f0327ec --- /dev/null +++ b/examples/operator__lessequal.output @@ -0,0 +1,4 @@ +[1,2,3] <= [1,2,4] true +{"A":"a","B":"b"} <= {"A":"a","B":"b"} true +17 <= 17.0000000000001 true +"foo" <= "bar" false diff --git a/examples/operator__notequal.cpp b/examples/operator__notequal.cpp new file mode 100644 index 000000000..43e89509c --- /dev/null +++ b/examples/operator__notequal.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/operator__notequal.output b/examples/operator__notequal.output new file mode 100644 index 000000000..6cbc0e8e6 --- /dev/null +++ b/examples/operator__notequal.output @@ -0,0 +1,4 @@ +[1,2,3] != [1,2,4] true +{"A":"a","B":"b"} != {"A":"a","B":"b"} false +17 != 17.0 false +"foo" != "bar" true diff --git a/examples/operator__notequal__nullptr_t.cpp b/examples/operator__notequal__nullptr_t.cpp new file mode 100644 index 000000000..dc7e6ac4c --- /dev/null +++ b/examples/operator__notequal__nullptr_t.cpp @@ -0,0 +1,22 @@ +#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'; +} diff --git a/examples/operator__notequal__nullptr_t.output b/examples/operator__notequal__nullptr_t.output new file mode 100644 index 000000000..0fc36dcf5 --- /dev/null +++ b/examples/operator__notequal__nullptr_t.output @@ -0,0 +1,5 @@ +[1,2,3] != nullptr true +{"A":"a","B":"b"} != nullptr true +17 != nullptr true +"foo" != nullptr true +null != nullptr false diff --git a/examples/operator__value_t.cpp b/examples/operator__value_t.cpp new file mode 100644 index 000000000..d9aac7978 --- /dev/null +++ b/examples/operator__value_t.cpp @@ -0,0 +1,38 @@ +#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'; +} diff --git a/examples/operator__value_t.output b/examples/operator__value_t.output new file mode 100644 index 000000000..310e632aa --- /dev/null +++ b/examples/operator__value_t.output @@ -0,0 +1,8 @@ +true +true +true +true +true +true +true +true diff --git a/examples/operator_array__json_pointer.cpp b/examples/operator_array__json_pointer.cpp new file mode 100644 index 000000000..0fa207f02 --- /dev/null +++ b/examples/operator_array__json_pointer.cpp @@ -0,0 +1,49 @@ +#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'; +} diff --git a/examples/operator_array__json_pointer.output b/examples/operator_array__json_pointer.output new file mode 100644 index 000000000..1fd1b032d --- /dev/null +++ b/examples/operator_array__json_pointer.output @@ -0,0 +1,8 @@ +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] diff --git a/examples/operator_array__json_pointer_const.cpp b/examples/operator_array__json_pointer_const.cpp new file mode 100644 index 000000000..f40e2494a --- /dev/null +++ b/examples/operator_array__json_pointer_const.cpp @@ -0,0 +1,25 @@ +#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'; +} diff --git a/examples/operator_array__json_pointer_const.output b/examples/operator_array__json_pointer_const.output new file mode 100644 index 000000000..7b9306bbc --- /dev/null +++ b/examples/operator_array__json_pointer_const.output @@ -0,0 +1,4 @@ +1 +"foo" +[1,2] +2 diff --git a/examples/operator_array__keytype.c++17.cpp b/examples/operator_array__keytype.c++17.cpp new file mode 100644 index 000000000..7f2b41dd8 --- /dev/null +++ b/examples/operator_array__keytype.c++17.cpp @@ -0,0 +1,34 @@ +#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'; +} diff --git a/examples/operator_array__keytype.c++17.output b/examples/operator_array__keytype.c++17.output new file mode 100644 index 000000000..b643587f1 --- /dev/null +++ b/examples/operator_array__keytype.c++17.output @@ -0,0 +1,19 @@ +2 + +{ + "one": 1, + "three": 3, + "two": 2 +} + +{ + "five": { + "really": { + "nested": true + } + }, + "four": null, + "one": 1, + "three": 3, + "two": 2 +} diff --git a/examples/operator_array__keytype_const.c++17.cpp b/examples/operator_array__keytype_const.c++17.cpp new file mode 100644 index 000000000..2cf94f40f --- /dev/null +++ b/examples/operator_array__keytype_const.c++17.cpp @@ -0,0 +1,18 @@ +#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'; +} diff --git a/examples/operator_array__keytype_const.c++17.output b/examples/operator_array__keytype_const.c++17.output new file mode 100644 index 000000000..0cfbf0888 --- /dev/null +++ b/examples/operator_array__keytype_const.c++17.output @@ -0,0 +1 @@ +2 diff --git a/examples/operator_array__object_t_key_type.cpp b/examples/operator_array__object_t_key_type.cpp new file mode 100644 index 000000000..f9b7f7318 --- /dev/null +++ b/examples/operator_array__object_t_key_type.cpp @@ -0,0 +1,32 @@ +#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'; +} diff --git a/examples/operator_array__object_t_key_type.output b/examples/operator_array__object_t_key_type.output new file mode 100644 index 000000000..b643587f1 --- /dev/null +++ b/examples/operator_array__object_t_key_type.output @@ -0,0 +1,19 @@ +2 + +{ + "one": 1, + "three": 3, + "two": 2 +} + +{ + "five": { + "really": { + "nested": true + } + }, + "four": null, + "one": 1, + "three": 3, + "two": 2 +} diff --git a/examples/operator_array__object_t_key_type_const.cpp b/examples/operator_array__object_t_key_type_const.cpp new file mode 100644 index 000000000..1bdb34024 --- /dev/null +++ b/examples/operator_array__object_t_key_type_const.cpp @@ -0,0 +1,16 @@ +#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'; +} diff --git a/examples/operator_array__object_t_key_type_const.output b/examples/operator_array__object_t_key_type_const.output new file mode 100644 index 000000000..0cfbf0888 --- /dev/null +++ b/examples/operator_array__object_t_key_type_const.output @@ -0,0 +1 @@ +2 diff --git a/examples/operator_array__size_type.cpp b/examples/operator_array__size_type.cpp new file mode 100644 index 000000000..d6f3e153c --- /dev/null +++ b/examples/operator_array__size_type.cpp @@ -0,0 +1,25 @@ +#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'; +} diff --git a/examples/operator_array__size_type.output b/examples/operator_array__size_type.output new file mode 100644 index 000000000..a91a10698 --- /dev/null +++ b/examples/operator_array__size_type.output @@ -0,0 +1,3 @@ +4 +[1,2,3,4,6] +[1,2,3,4,6,null,null,null,null,null,11] diff --git a/examples/operator_array__size_type_const.cpp b/examples/operator_array__size_type_const.cpp new file mode 100644 index 000000000..d56fa0a43 --- /dev/null +++ b/examples/operator_array__size_type_const.cpp @@ -0,0 +1,13 @@ +#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'; +} diff --git a/examples/operator_array__size_type_const.output b/examples/operator_array__size_type_const.output new file mode 100644 index 000000000..4450c9f00 --- /dev/null +++ b/examples/operator_array__size_type_const.output @@ -0,0 +1 @@ +"third" diff --git a/examples/operator_deserialize.cpp b/examples/operator_deserialize.cpp new file mode 100644 index 000000000..8e3d8bd83 --- /dev/null +++ b/examples/operator_deserialize.cpp @@ -0,0 +1,26 @@ +#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'; +} diff --git a/examples/operator_deserialize.output b/examples/operator_deserialize.output new file mode 100644 index 000000000..81a203fb0 --- /dev/null +++ b/examples/operator_deserialize.output @@ -0,0 +1,13 @@ +{ + "array": [ + 1, + 2, + 3, + 4, + 5 + ], + "boolean": false, + "null": null, + "number": 23, + "string": "Hello, world!" +} diff --git a/examples/operator_literal_json.cpp b/examples/operator_literal_json.cpp new file mode 100644 index 000000000..84ca6297d --- /dev/null +++ b/examples/operator_literal_json.cpp @@ -0,0 +1,13 @@ +#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'; +} diff --git a/examples/operator_literal_json.output b/examples/operator_literal_json.output new file mode 100644 index 000000000..6c0a7b34b --- /dev/null +++ b/examples/operator_literal_json.output @@ -0,0 +1,4 @@ +{ + "answer": 42, + "hello": "world" +} diff --git a/examples/operator_literal_json_pointer.cpp b/examples/operator_literal_json_pointer.cpp new file mode 100644 index 000000000..aba93e88e --- /dev/null +++ b/examples/operator_literal_json_pointer.cpp @@ -0,0 +1,14 @@ +#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'; +} diff --git a/examples/operator_literal_json_pointer.output b/examples/operator_literal_json_pointer.output new file mode 100644 index 000000000..b0fcd3479 --- /dev/null +++ b/examples/operator_literal_json_pointer.output @@ -0,0 +1 @@ +"world" diff --git a/examples/operator_ltlt__basic_json.cpp b/examples/operator_ltlt__basic_json.cpp new file mode 100644 index 000000000..3bd4ad577 --- /dev/null +++ b/examples/operator_ltlt__basic_json.cpp @@ -0,0 +1,21 @@ +#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"; +} diff --git a/examples/operator_ltlt__basic_json.output b/examples/operator_ltlt__basic_json.output new file mode 100644 index 000000000..7e86bfa2e --- /dev/null +++ b/examples/operator_ltlt__basic_json.output @@ -0,0 +1,22 @@ +{"one":1,"two":2} + +[1,2,4,8,16] + +{ + "one": 1, + "two": 2 +} + +[ + 1, + 2, + 4, + 8, + 16 +] + +{ + "one": 1, + "two": 2 +} + diff --git a/examples/operator_ltlt__json_pointer.cpp b/examples/operator_ltlt__json_pointer.cpp new file mode 100644 index 000000000..f4fac886d --- /dev/null +++ b/examples/operator_ltlt__json_pointer.cpp @@ -0,0 +1,13 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON poiner + json::json_pointer ptr("/foo/bar/baz"); + + // write string representation to stream + std::cout << ptr << std::endl; +} diff --git a/examples/operator_ltlt__json_pointer.output b/examples/operator_ltlt__json_pointer.output new file mode 100644 index 000000000..ed359432d --- /dev/null +++ b/examples/operator_ltlt__json_pointer.output @@ -0,0 +1 @@ +/foo/bar/baz diff --git a/examples/operator_spaceship__const_reference.c++20.cpp b/examples/operator_spaceship__const_reference.c++20.cpp new file mode 100644 index 000000000..3c6c8b8c5 --- /dev/null +++ b/examples/operator_spaceship__const_reference.c++20.cpp @@ -0,0 +1,41 @@ +#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* +} diff --git a/examples/operator_spaceship__const_reference.c++20.output b/examples/operator_spaceship__const_reference.c++20.output new file mode 100644 index 000000000..2e8bf9f64 --- /dev/null +++ b/examples/operator_spaceship__const_reference.c++20.output @@ -0,0 +1,4 @@ +[1,2,3] <=> [1,2,4] := less +{"A":"a","B":"b"} <=> {"A":"a","B":"b"} := equivalent +"foo" <=> 17 := greater +"foo" <=> := unordered diff --git a/examples/operator_spaceship__scalartype.c++20.cpp b/examples/operator_spaceship__scalartype.c++20.cpp new file mode 100644 index 000000000..d9dc3ca49 --- /dev/null +++ b/examples/operator_spaceship__scalartype.c++20.cpp @@ -0,0 +1,41 @@ +#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* +} diff --git a/examples/operator_spaceship__scalartype.c++20.output b/examples/operator_spaceship__scalartype.c++20.output new file mode 100644 index 000000000..b2939a5f5 --- /dev/null +++ b/examples/operator_spaceship__scalartype.c++20.output @@ -0,0 +1,4 @@ +false <=> true := less +17 <=> 17.000000 := equivalent +17 <=> nan := unordered +"17" <=> 17 := greater diff --git a/examples/ordered_json.cpp b/examples/ordered_json.cpp new file mode 100644 index 000000000..effad530c --- /dev/null +++ b/examples/ordered_json.cpp @@ -0,0 +1,14 @@ +#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'; +} diff --git a/examples/ordered_json.output b/examples/ordered_json.output new file mode 100644 index 000000000..120cbb284 --- /dev/null +++ b/examples/ordered_json.output @@ -0,0 +1,5 @@ +{ + "one": 1, + "two": 2, + "three": 3 +} diff --git a/examples/ordered_map.cpp b/examples/ordered_map.cpp new file mode 100644 index 000000000..dcc60cb52 --- /dev/null +++ b/examples/ordered_map.cpp @@ -0,0 +1,43 @@ +#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); +} diff --git a/examples/ordered_map.output b/examples/ordered_map.output new file mode 100644 index 000000000..a4ffc454a --- /dev/null +++ b/examples/ordered_map.output @@ -0,0 +1,4 @@ +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 } diff --git a/examples/other_error.cpp b/examples/other_error.cpp new file mode 100644 index 000000000..99c4be70e --- /dev/null +++ b/examples/other_error.cpp @@ -0,0 +1,30 @@ +#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 (json::other_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/examples/other_error.output b/examples/other_error.output new file mode 100644 index 000000000..b80f1cb38 --- /dev/null +++ b/examples/other_error.output @@ -0,0 +1,2 @@ +message: [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/best_biscuit/name","value":"Choco Leibniz"} +exception id: 501 diff --git a/examples/out_of_range.cpp b/examples/out_of_range.cpp new file mode 100644 index 000000000..e7116408a --- /dev/null +++ b/examples/out_of_range.cpp @@ -0,0 +1,20 @@ +#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 (json::out_of_range& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/examples/out_of_range.output b/examples/out_of_range.output new file mode 100644 index 000000000..29ec76b3c --- /dev/null +++ b/examples/out_of_range.output @@ -0,0 +1,2 @@ +message: [json.exception.out_of_range.401] array index 4 is out of range +exception id: 401 diff --git a/examples/parse__allow_exceptions.cpp b/examples/parse__allow_exceptions.cpp new file mode 100644 index 000000000..82449a526 --- /dev/null +++ b/examples/parse__allow_exceptions.cpp @@ -0,0 +1,36 @@ +#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 (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; + } +} diff --git a/examples/parse__allow_exceptions.output b/examples/parse__allow_exceptions.output new file mode 100644 index 000000000..d650824d2 --- /dev/null +++ b/examples/parse__allow_exceptions.output @@ -0,0 +1,2 @@ +[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 diff --git a/examples/parse__array__parser_callback_t.cpp b/examples/parse__array__parser_callback_t.cpp new file mode 100644 index 000000000..63f0a0e4d --- /dev/null +++ b/examples/parse__array__parser_callback_t.cpp @@ -0,0 +1,30 @@ +#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"; +} diff --git a/examples/parse__array__parser_callback_t.output b/examples/parse__array__parser_callback_t.output new file mode 100644 index 000000000..62bb85863 --- /dev/null +++ b/examples/parse__array__parser_callback_t.output @@ -0,0 +1,20 @@ +{ + "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 + } +} + diff --git a/examples/parse__contiguouscontainer__parser_callback_t.cpp b/examples/parse__contiguouscontainer__parser_callback_t.cpp new file mode 100644 index 000000000..6eb409bba --- /dev/null +++ b/examples/parse__contiguouscontainer__parser_callback_t.cpp @@ -0,0 +1,15 @@ +#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"; +} diff --git a/examples/parse__contiguouscontainer__parser_callback_t.output b/examples/parse__contiguouscontainer__parser_callback_t.output new file mode 100644 index 000000000..74633e808 --- /dev/null +++ b/examples/parse__contiguouscontainer__parser_callback_t.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/examples/parse__istream__parser_callback_t.cpp b/examples/parse__istream__parser_callback_t.cpp new file mode 100644 index 000000000..afcaa39d0 --- /dev/null +++ b/examples/parse__istream__parser_callback_t.cpp @@ -0,0 +1,58 @@ +#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'; +} \ No newline at end of file diff --git a/examples/parse__istream__parser_callback_t.output b/examples/parse__istream__parser_callback_t.output new file mode 100644 index 000000000..279a7ff74 --- /dev/null +++ b/examples/parse__istream__parser_callback_t.output @@ -0,0 +1,34 @@ +{ + "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/examples/parse__iterator_pair.cpp b/examples/parse__iterator_pair.cpp new file mode 100644 index 000000000..d0c30c1a5 --- /dev/null +++ b/examples/parse__iterator_pair.cpp @@ -0,0 +1,15 @@ +#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"; +} diff --git a/examples/parse__iterator_pair.output b/examples/parse__iterator_pair.output new file mode 100644 index 000000000..74633e808 --- /dev/null +++ b/examples/parse__iterator_pair.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/examples/parse__pointers.cpp b/examples/parse__pointers.cpp new file mode 100644 index 000000000..a5a16eea9 --- /dev/null +++ b/examples/parse__pointers.cpp @@ -0,0 +1,15 @@ +#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"; +} diff --git a/examples/parse__pointers.output b/examples/parse__pointers.output new file mode 100644 index 000000000..74633e808 --- /dev/null +++ b/examples/parse__pointers.output @@ -0,0 +1,6 @@ +[ + 1, + 2, + 3 +] + diff --git a/examples/parse__string__parser_callback_t.cpp b/examples/parse__string__parser_callback_t.cpp new file mode 100644 index 000000000..2ae4410a8 --- /dev/null +++ b/examples/parse__string__parser_callback_t.cpp @@ -0,0 +1,49 @@ +#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'; +} diff --git a/examples/parse__string__parser_callback_t.output b/examples/parse__string__parser_callback_t.output new file mode 100644 index 000000000..279a7ff74 --- /dev/null +++ b/examples/parse__string__parser_callback_t.output @@ -0,0 +1,34 @@ +{ + "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/examples/parse_error.cpp b/examples/parse_error.cpp new file mode 100644 index 000000000..9b27b58fa --- /dev/null +++ b/examples/parse_error.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + try + { + // parsing input with a syntax error + json::parse("[1,2,3,]"); + } + catch (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; + } +} diff --git a/examples/parse_error.output b/examples/parse_error.output new file mode 100644 index 000000000..fe366ff8a --- /dev/null +++ b/examples/parse_error.output @@ -0,0 +1,3 @@ +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 diff --git a/examples/patch.cpp b/examples/patch.cpp new file mode 100644 index 000000000..b7ecb8eee --- /dev/null +++ b/examples/patch.cpp @@ -0,0 +1,33 @@ +#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; +} diff --git a/examples/patch.output b/examples/patch.output new file mode 100644 index 000000000..eb558fe25 --- /dev/null +++ b/examples/patch.output @@ -0,0 +1,11 @@ +{ + "baz": "qux", + "foo": "bar" +} + +{ + "baz": "boo", + "hello": [ + "world" + ] +} diff --git a/examples/patch_inplace.cpp b/examples/patch_inplace.cpp new file mode 100644 index 000000000..061708a2d --- /dev/null +++ b/examples/patch_inplace.cpp @@ -0,0 +1,35 @@ +#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; +} diff --git a/examples/patch_inplace.output b/examples/patch_inplace.output new file mode 100644 index 000000000..9d31b8ba4 --- /dev/null +++ b/examples/patch_inplace.output @@ -0,0 +1,13 @@ +Before +{ + "baz": "qux", + "foo": "bar" +} + +After +{ + "baz": "boo", + "hello": [ + "world" + ] +} diff --git a/examples/push_back.cpp b/examples/push_back.cpp new file mode 100644 index 000000000..bbddf4f51 --- /dev/null +++ b/examples/push_back.cpp @@ -0,0 +1,25 @@ +#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'; +} diff --git a/examples/push_back.output b/examples/push_back.output new file mode 100644 index 000000000..3306b60e3 --- /dev/null +++ b/examples/push_back.output @@ -0,0 +1,4 @@ +[1,2,3,4,5] +null +[1,2,3,4,5,6,7] +["first","second"] diff --git a/examples/push_back__initializer_list.cpp b/examples/push_back__initializer_list.cpp new file mode 100644 index 000000000..e96645f16 --- /dev/null +++ b/examples/push_back__initializer_list.cpp @@ -0,0 +1,27 @@ +#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}); +} diff --git a/examples/push_back__initializer_list.output b/examples/push_back__initializer_list.output new file mode 100644 index 000000000..668eb25d7 --- /dev/null +++ b/examples/push_back__initializer_list.output @@ -0,0 +1,4 @@ +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +[["five",5]] diff --git a/examples/push_back__object_t__value.cpp b/examples/push_back__object_t__value.cpp new file mode 100644 index 000000000..5d694e938 --- /dev/null +++ b/examples/push_back__object_t__value.cpp @@ -0,0 +1,25 @@ +#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'; +} diff --git a/examples/push_back__object_t__value.output b/examples/push_back__object_t__value.output new file mode 100644 index 000000000..b8a7d3560 --- /dev/null +++ b/examples/push_back__object_t__value.output @@ -0,0 +1,4 @@ +{"one":1,"two":2} +null +{"four":4,"one":1,"three":3,"two":2} +{"A":"a","B":"b"} diff --git a/examples/rbegin.cpp b/examples/rbegin.cpp new file mode 100644 index 000000000..239f7a689 --- /dev/null +++ b/examples/rbegin.cpp @@ -0,0 +1,16 @@ +#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'; +} diff --git a/examples/rbegin.output b/examples/rbegin.output new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/examples/rbegin.output @@ -0,0 +1 @@ +5 diff --git a/examples/rend.cpp b/examples/rend.cpp new file mode 100644 index 000000000..adadbbdc2 --- /dev/null +++ b/examples/rend.cpp @@ -0,0 +1,19 @@ +#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'; +} diff --git a/examples/rend.output b/examples/rend.output new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/examples/rend.output @@ -0,0 +1 @@ +1 diff --git a/examples/sax_parse.cpp b/examples/sax_parse.cpp new file mode 100644 index 000000000..8602687e3 --- /dev/null +++ b/examples/sax_parse.cpp @@ -0,0 +1,131 @@ +#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; +} diff --git a/examples/sax_parse.output b/examples/sax_parse.output new file mode 100644 index 000000000..dd2fc2f05 --- /dev/null +++ b/examples/sax_parse.output @@ -0,0 +1,37 @@ +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 diff --git a/examples/sax_parse__binary.cpp b/examples/sax_parse__binary.cpp new file mode 100644 index 000000000..08bc85df6 --- /dev/null +++ b/examples/sax_parse__binary.cpp @@ -0,0 +1,114 @@ +#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; +} diff --git a/examples/sax_parse__binary.output b/examples/sax_parse__binary.output new file mode 100644 index 000000000..f88089610 --- /dev/null +++ b/examples/sax_parse__binary.output @@ -0,0 +1,3 @@ +binary(val=[...]) + +result: true diff --git a/examples/size.cpp b/examples/size.cpp new file mode 100644 index 000000000..237548377 --- /dev/null +++ b/examples/size.cpp @@ -0,0 +1,29 @@ +#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'; +} diff --git a/examples/size.output b/examples/size.output new file mode 100644 index 000000000..3831387b1 --- /dev/null +++ b/examples/size.output @@ -0,0 +1,9 @@ +0 +1 +1 +1 +2 +0 +5 +0 +1 diff --git a/examples/std_hash.cpp b/examples/std_hash.cpp new file mode 100644 index 000000000..9721910eb --- /dev/null +++ b/examples/std_hash.cpp @@ -0,0 +1,19 @@ +#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; +} diff --git a/examples/std_hash.output b/examples/std_hash.output new file mode 100644 index 000000000..521d2b4b8 --- /dev/null +++ b/examples/std_hash.output @@ -0,0 +1,8 @@ +hash(null) = 2654435769 +hash(false) = 2654436030 +hash(0) = 2654436095 +hash(0U) = 2654436156 +hash("") = 6142509191626859748 +hash({}) = 2654435832 +hash([]) = 2654435899 +hash({"hello": "world"}) = 4469488738203676328 diff --git a/examples/std_swap.cpp b/examples/std_swap.cpp new file mode 100644 index 000000000..36ab3ce6b --- /dev/null +++ b/examples/std_swap.cpp @@ -0,0 +1,19 @@ +#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; +} diff --git a/examples/std_swap.output b/examples/std_swap.output new file mode 100644 index 000000000..5ae6db780 --- /dev/null +++ b/examples/std_swap.output @@ -0,0 +1,2 @@ +j1 = {"one":1,"two":2} | j2 = [1,2,4,8,16] +j1 = [1,2,4,8,16] | j2 = {"one":1,"two":2} diff --git a/examples/string_t.cpp b/examples/string_t.cpp new file mode 100644 index 000000000..77a9ea480 --- /dev/null +++ b/examples/string_t.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::boolalpha << std::is_same::value << std::endl; +} diff --git a/examples/string_t.output b/examples/string_t.output new file mode 100644 index 000000000..27ba77dda --- /dev/null +++ b/examples/string_t.output @@ -0,0 +1 @@ +true diff --git a/examples/swap__array_t.cpp b/examples/swap__array_t.cpp new file mode 100644 index 000000000..2119dd552 --- /dev/null +++ b/examples/swap__array_t.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/swap__array_t.output b/examples/swap__array_t.output new file mode 100644 index 000000000..365302cc1 --- /dev/null +++ b/examples/swap__array_t.output @@ -0,0 +1,2 @@ +value = {"array":["Snap","Crackle","Pop"]} +array = [1,2,3,4] diff --git a/examples/swap__binary_t.cpp b/examples/swap__binary_t.cpp new file mode 100644 index 000000000..4b8fc3db7 --- /dev/null +++ b/examples/swap__binary_t.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/swap__binary_t.output b/examples/swap__binary_t.output new file mode 100644 index 000000000..68cd76892 --- /dev/null +++ b/examples/swap__binary_t.output @@ -0,0 +1,2 @@ +value = {"bytes":[4,5,6],"subtype":null} +binary = {"bytes":[1,2,3],"subtype":null} diff --git a/examples/swap__object_t.cpp b/examples/swap__object_t.cpp new file mode 100644 index 000000000..301b558d3 --- /dev/null +++ b/examples/swap__object_t.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/swap__object_t.output b/examples/swap__object_t.output new file mode 100644 index 000000000..b5c9791bf --- /dev/null +++ b/examples/swap__object_t.output @@ -0,0 +1,2 @@ +value = {"translation":{"cow":"Kuh","dog":"Hund"}} +object = {"one":"eins","two":"zwei"} diff --git a/examples/swap__reference.cpp b/examples/swap__reference.cpp new file mode 100644 index 000000000..34182ad24 --- /dev/null +++ b/examples/swap__reference.cpp @@ -0,0 +1,18 @@ +#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'; +} diff --git a/examples/swap__reference.output b/examples/swap__reference.output new file mode 100644 index 000000000..96b07b094 --- /dev/null +++ b/examples/swap__reference.output @@ -0,0 +1,2 @@ +j1 = {"e":2.718281828459045,"pi":3.141592653589793} +j2 = [1,2,3,4,5] diff --git a/examples/swap__string_t.cpp b/examples/swap__string_t.cpp new file mode 100644 index 000000000..b5d58316f --- /dev/null +++ b/examples/swap__string_t.cpp @@ -0,0 +1,20 @@ +#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'; +} diff --git a/examples/swap__string_t.output b/examples/swap__string_t.output new file mode 100644 index 000000000..ae2a0976b --- /dev/null +++ b/examples/swap__string_t.output @@ -0,0 +1,2 @@ +value = ["the good","the fast","the ugly"] +string = the bad diff --git a/examples/to_bjdata.cpp b/examples/to_bjdata.cpp new file mode 100644 index 000000000..9b7abac4e --- /dev/null +++ b/examples/to_bjdata.cpp @@ -0,0 +1,64 @@ +#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; +} diff --git a/examples/to_bjdata.output b/examples/to_bjdata.output new file mode 100644 index 000000000..087980cb9 --- /dev/null +++ b/examples/to_bjdata.output @@ -0,0 +1,4 @@ +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 diff --git a/examples/to_bson.cpp b/examples/to_bson.cpp new file mode 100644 index 000000000..3484b0b76 --- /dev/null +++ b/examples/to_bson.cpp @@ -0,0 +1,22 @@ +#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; +} diff --git a/examples/to_bson.output b/examples/to_bson.output new file mode 100644 index 000000000..379532a2f --- /dev/null +++ b/examples/to_bson.output @@ -0,0 +1 @@ +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 diff --git a/examples/to_cbor.cpp b/examples/to_cbor.cpp new file mode 100644 index 000000000..3d5e04150 --- /dev/null +++ b/examples/to_cbor.cpp @@ -0,0 +1,22 @@ +#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; +} diff --git a/examples/to_cbor.output b/examples/to_cbor.output new file mode 100644 index 000000000..02c9adab3 --- /dev/null +++ b/examples/to_cbor.output @@ -0,0 +1 @@ +0xa2 0x67 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xf5 0x66 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 diff --git a/examples/to_json.cpp b/examples/to_json.cpp new file mode 100644 index 000000000..1f82a4de4 --- /dev/null +++ b/examples/to_json.cpp @@ -0,0 +1,32 @@ +#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; +} diff --git a/examples/to_json.output b/examples/to_json.output new file mode 100644 index 000000000..e9c5bf381 --- /dev/null +++ b/examples/to_json.output @@ -0,0 +1 @@ +{"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} diff --git a/examples/to_msgpack.cpp b/examples/to_msgpack.cpp new file mode 100644 index 000000000..b29ae8c7c --- /dev/null +++ b/examples/to_msgpack.cpp @@ -0,0 +1,22 @@ +#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; +} diff --git a/examples/to_msgpack.output b/examples/to_msgpack.output new file mode 100644 index 000000000..4d6c40aba --- /dev/null +++ b/examples/to_msgpack.output @@ -0,0 +1 @@ +0x82 0xa7 0x63 0x6f 0x6d 0x70 0x61 0x63 0x74 0xc3 0xa6 0x73 0x63 0x68 0x65 0x6d 0x61 0x00 diff --git a/examples/to_string.cpp b/examples/to_string.cpp new file mode 100644 index 000000000..ee44283f3 --- /dev/null +++ b/examples/to_string.cpp @@ -0,0 +1,20 @@ +#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; +} diff --git a/examples/to_string.output b/examples/to_string.output new file mode 100644 index 000000000..b261f35e3 --- /dev/null +++ b/examples/to_string.output @@ -0,0 +1,3 @@ +{"one":1,"two":2} + +42 diff --git a/examples/to_ubjson.cpp b/examples/to_ubjson.cpp new file mode 100644 index 000000000..fd267a85a --- /dev/null +++ b/examples/to_ubjson.cpp @@ -0,0 +1,64 @@ +#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; +} diff --git a/examples/to_ubjson.output b/examples/to_ubjson.output new file mode 100644 index 000000000..087980cb9 --- /dev/null +++ b/examples/to_ubjson.output @@ -0,0 +1,4 @@ +{i7compactTi6schemaF} +[i1i2i3i4i5i6i7i8] +[#i8i1i2i3i4i5i6i7i8 +[$i#i812345678 diff --git a/examples/type.cpp b/examples/type.cpp new file mode 100644 index 000000000..68fba3a91 --- /dev/null +++ b/examples/type.cpp @@ -0,0 +1,28 @@ +#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'; +} diff --git a/examples/type.output b/examples/type.output new file mode 100644 index 000000000..310e632aa --- /dev/null +++ b/examples/type.output @@ -0,0 +1,8 @@ +true +true +true +true +true +true +true +true diff --git a/examples/type_error.cpp b/examples/type_error.cpp new file mode 100644 index 000000000..d4f18b180 --- /dev/null +++ b/examples/type_error.cpp @@ -0,0 +1,20 @@ +#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 (json::type_error& e) + { + // output exception information + std::cout << "message: " << e.what() << '\n' + << "exception id: " << e.id << std::endl; + } +} diff --git a/examples/type_error.output b/examples/type_error.output new file mode 100644 index 000000000..1a6733907 --- /dev/null +++ b/examples/type_error.output @@ -0,0 +1,2 @@ +message: [json.exception.type_error.308] cannot use push_back() with string +exception id: 308 diff --git a/examples/type_name.cpp b/examples/type_name.cpp new file mode 100644 index 000000000..32d3590cc --- /dev/null +++ b/examples/type_name.cpp @@ -0,0 +1,27 @@ +#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'; +} diff --git a/examples/type_name.output b/examples/type_name.output new file mode 100644 index 000000000..f394e819f --- /dev/null +++ b/examples/type_name.output @@ -0,0 +1,8 @@ +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 diff --git a/examples/unflatten.cpp b/examples/unflatten.cpp new file mode 100644 index 000000000..75fb02d03 --- /dev/null +++ b/examples/unflatten.cpp @@ -0,0 +1,26 @@ +#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'; +} diff --git a/examples/unflatten.output b/examples/unflatten.output new file mode 100644 index 000000000..ed48385ae --- /dev/null +++ b/examples/unflatten.output @@ -0,0 +1,18 @@ +{ + "answer": { + "everything": 42 + }, + "happy": true, + "list": [ + 1, + 0, + 2 + ], + "name": "Niels", + "nothing": null, + "object": { + "currency": "USD", + "value": 42.99 + }, + "pi": 3.141 +} diff --git a/examples/update.cpp b/examples/update.cpp new file mode 100644 index 000000000..ff94b67fa --- /dev/null +++ b/examples/update.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/update.output b/examples/update.output new file mode 100644 index 000000000..c35a74513 --- /dev/null +++ b/examples/update.output @@ -0,0 +1,17 @@ +{ + "color": "blue", + "names": { + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +{ + "color": "blue", + "names": { + "de": "Flugzeug", + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} diff --git a/examples/update__range.cpp b/examples/update__range.cpp new file mode 100644 index 000000000..5b4385046 --- /dev/null +++ b/examples/update__range.cpp @@ -0,0 +1,24 @@ +#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'; +} diff --git a/examples/update__range.output b/examples/update__range.output new file mode 100644 index 000000000..c35a74513 --- /dev/null +++ b/examples/update__range.output @@ -0,0 +1,17 @@ +{ + "color": "blue", + "names": { + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} +{ + "color": "blue", + "names": { + "de": "Flugzeug", + "en": "plane" + }, + "price": 17.99, + "speed": 100 +} diff --git a/examples/value__json_ptr.cpp b/examples/value__json_ptr.cpp new file mode 100644 index 000000000..d866ef076 --- /dev/null +++ b/examples/value__json_ptr.cpp @@ -0,0 +1,31 @@ +#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"; +} diff --git a/examples/value__json_ptr.output b/examples/value__json_ptr.output new file mode 100644 index 000000000..dfc40e58c --- /dev/null +++ b/examples/value__json_ptr.output @@ -0,0 +1 @@ +1 42.23 oops false diff --git a/examples/value__keytype.c++17.cpp b/examples/value__keytype.c++17.cpp new file mode 100644 index 000000000..1f6ff5c30 --- /dev/null +++ b/examples/value__keytype.c++17.cpp @@ -0,0 +1,32 @@ +#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"; +} diff --git a/examples/value__keytype.c++17.output b/examples/value__keytype.c++17.output new file mode 100644 index 000000000..dfc40e58c --- /dev/null +++ b/examples/value__keytype.c++17.output @@ -0,0 +1 @@ +1 42.23 oops false diff --git a/examples/value__object_t_key_type.cpp b/examples/value__object_t_key_type.cpp new file mode 100644 index 000000000..9488d30ef --- /dev/null +++ b/examples/value__object_t_key_type.cpp @@ -0,0 +1,30 @@ +#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"; +} diff --git a/examples/value__object_t_key_type.output b/examples/value__object_t_key_type.output new file mode 100644 index 000000000..dfc40e58c --- /dev/null +++ b/examples/value__object_t_key_type.output @@ -0,0 +1 @@ +1 42.23 oops false diff --git a/features/arbitrary_types/index.html b/features/arbitrary_types/index.html new file mode 100644 index 000000000..7162810e0 --- /dev/null +++ b/features/arbitrary_types/index.html @@ -0,0 +1,162 @@ + Arbitrary Type Conversions - JSON for Modern C++

    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<std::string>(),
    +    j["address"].get<std::string>(),
    +    j["age"].get<int>()
    +};
    +

    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<ns::person>();
    +
    +// 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<your_type>() 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 issue 1108 for errors that may occur otherwise.
    • When using get<your_type>(), your_type MUST be DefaultConstructible. (There is a way to bypass this requirement described later.)
    • In function from_json, use function at() 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 four macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object:

    In all macros, the first parameter is the name of the class/struct, and all remaining parameters name the members. You can read more docs about them starting from here.

    Implementation limits

    • The current macro implementations are limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json/from_json functions manually.
    • The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported.
    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)
    +}
    +

    Here is an 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)
    +    };
    +}
    +

    How do I convert third-party types?

    This requires a bit more advanced technique. But first, let's 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).

    It is implemented like this (simplified):

    template <typename T>
    +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 <typename T>
    +struct adl_serializer<boost::optional<T>> {
    +    static void to_json(json& j, const boost::optional<T>& opt) {
    +        if (opt == boost::none) {
    +            j = nullptr;
    +        } else {
    +            j = *opt; // this will call adl_serializer<T>::to_json which will
    +                      // find the free function to_json in T's namespace!
    +        }
    +    }
    +
    +    static void from_json(const json& j, boost::optional<T>& opt) {
    +        if (j.is_null()) {
    +            opt = boost::none;
    +        } else {
    +            opt = j.get<T>(); // same as above, but with
    +                              // adl_serializer<T>::from_json
    +        }
    +    }
    +};
    +NLOHMANN_JSON_NAMESPACE_END
    +

    ABI compatibility

    Use NLOHMANN_JSON_NAMESPACE_BEGIN 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. 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<move_only_type> {
    +        // 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<int>()};
    +        }
    +
    +        // 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 in the test suite, to see a few examples.

    If you write your own serializer, you'll 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<typename T, typename SFINAE = typename std::enable_if<sizeof(T) <= 32>::type>
    +struct less_than_32_serializer {
    +    template <typename BasicJsonType>
    +    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 <typename BasicJsonType>
    +    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 <typename T, void>
    +struct bad_serializer
    +{
    +    template <typename BasicJsonType>
    +    static void to_json(BasicJsonType& j, const T& value) {
    +      // this calls BasicJsonType::json_serializer<T>::to_json(j, value);
    +      // if BasicJsonType::json_serializer == bad_serializer ... oops!
    +      j = value;
    +    }
    +
    +    template <typename BasicJsonType>
    +    static void to_json(const BasicJsonType& j, T& value) {
    +      // this calls BasicJsonType::json_serializer<T>::from_json(j, value);
    +      // if BasicJsonType::json_serializer == bad_serializer ... oops!
    +      value = j.template get<T>(); // oops!
    +    }
    +};
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/assertions/index.html b/features/assertions/index.html new file mode 100644 index 000000000..afed3d10d --- /dev/null +++ b/features/assertions/index.html @@ -0,0 +1,41 @@ + Runtime Assertions - JSON for Modern C++

    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 of, 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) which is the default for release builds.

    Change assertion behavior

    The behavior of runtime assertions can be changes by defining macro JSON_ASSERT(x) before including the json.hpp header.

    Function with runtime assertions

    Unchecked object access to a const value

    Function operator[] implements unchecked access for objects. Whereas a missing key is added in 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 or call the contains function before.

    See also the documentation on element access.

    Example 1: Missing object key

    The following code will trigger an assertion at runtime:

    #include <nlohmann/json.hpp>
    +
    +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) 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 <nlohmann/json.hpp>
    +
    +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 <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +  json::iterator it;
    +  ++it;
    +}
    +

    Output:

    Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.
    +

    Reading from a null FILE pointer

    Reading from a null FILE pointer is undefined behavior and yields a runtime assertion. This can happen when calling std::fopen on a nonexistent file.

    Example 4: Uninitialized iterator

    The following code will trigger an assertion at runtime:

    #include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +  std::FILE* f = std::fopen("nonexistent_file.json", "r");
    +  json j = json::parse(f);
    +}
    +

    Output:

    Assertion failed: (m_file != nullptr), function file_input_adapter, file input_adapters.hpp, line 55.
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/binary_formats/bjdata/index.html b/features/binary_formats/bjdata/index.html new file mode 100644 index 000000000..48b790468 --- /dev/null +++ b/features/binary_formats/bjdata/index.html @@ -0,0 +1,98 @@ + BJData - JSON for Modern C++

    BJData

    The BJData format was derived from and improved upon Universal Binary JSON(UBJSON) specification (Draft 12). Specifically, it introduces an optimized array container for efficient storage of N-dimensional packed arrays (ND-arrays); it also adds 4 new type markers - [u] - uint16, [m] - uint32, [M] - uint64 and [h] - float16 - 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 are not only compact in size, fast to read/write, but also can be directly searched or read using simple processing.

    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 {

    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:

    • 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)), when parsed using from_bjdata. 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 serialzed using to_bjdata, 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 UiuImlMLhdDC. 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

    If the JSON data contains the binary type, the value stored is 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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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<std::uint8_t> 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<std::uint8_t> v_array = json::to_bjdata(array);
    +    // serialize it to BJData using size optimization
    +    std::vector<std::uint8_t> v_array_size = json::to_bjdata(array, true);
    +    // serialize it to BJData using type optimization
    +    std::vector<std::uint8_t> 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
    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) {

    Complete mapping

    The mapping is complete in the sense that any BJData value can be converted to a JSON value.

    Example
    #include <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    // create byte vector
    +    std::vector<std::uint8_t> 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
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/binary_formats/bson/index.html b/features/binary_formats/bson/index.html new file mode 100644 index 000000000..e49097edd --- /dev/null +++ b/features/binary_formats/bson/index.html @@ -0,0 +1,49 @@ + BSON - JSON for Modern C++

    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

    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 -- --
    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, integers larger than 9223372036854775807 cannot be serialized to BSON, and the keys may not contain U+0000, since they are serialized a zero-terminated c-strings.

    Example
    #include <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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<std::uint8_t> 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 0x0F unsupported
    int32 0x10 number_integer
    Timestamp 0x11 unsupported
    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.

    Example
    #include <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    // create byte vector
    +    std::vector<std::uint8_t> 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
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/binary_formats/cbor/index.html b/features/binary_formats/cbor/index.html new file mode 100644 index 000000000..57eeae31d --- /dev/null +++ b/features/binary_formats/cbor/index.html @@ -0,0 +1,48 @@ + CBOR - JSON for Modern C++

    CBOR

    The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation.

    References

    Serialization

    The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification (RFC 7049):

    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: 23..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: 23..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: 23..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: 23..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 for an example.

    Example
    #include <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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<std::uint8_t> 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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    // create byte vector
    +    std::vector<std::uint8_t> 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
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/binary_formats/index.html b/features/binary_formats/index.html new file mode 100644 index 000000000..9aeacdc68 --- /dev/null +++ b/features/binary_formats/index.html @@ -0,0 +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+tyoe) 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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/binary_formats/messagepack/index.html b/features/binary_formats/messagepack/index.html new file mode 100644 index 000000000..a6fe4eb6f --- /dev/null +++ b/features/binary_formats/messagepack/index.html @@ -0,0 +1,48 @@ + MessagePack - JSON for Modern C++

    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.

    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 function which serializes NaN or Infinity to null.

    Example
    #include <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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<std::uint8_t> 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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    // create byte vector
    +    std::vector<std::uint8_t> 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
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/binary_formats/ubjson/index.html b/features/binary_formats/ubjson/index.html new file mode 100644 index 000000000..0750858f8 --- /dev/null +++ b/features/binary_formats/ubjson/index.html @@ -0,0 +1,93 @@ + UBJSON - JSON for Modern C++

    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

    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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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<std::uint8_t> 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<std::uint8_t> v_array = json::to_ubjson(array);
    +    // serialize it to UBJSON using size optimization
    +    std::vector<std::uint8_t> v_array_size = json::to_ubjson(array, true);
    +    // serialize it to UBJSON using type optimization
    +    std::vector<std::uint8_t> 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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    // create byte vector
    +    std::vector<std::uint8_t> 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
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/binary_values/index.html b/features/binary_values/index.html new file mode 100644 index 000000000..b2c909d63 --- /dev/null +++ b/features/binary_values/index.html @@ -0,0 +1,146 @@ + Binary Values - JSON for Modern C++

    Binary Values

    The library implements several binary formats that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics define 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

    uml diagram

    By default, binary values are stored as std::vector<std::uint8_t>. 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 true
    +
    +binary_with_subtype.set_subtype(42);
    +binary.set_subtype(23);
    +
    +binary.subtype();                       // returns 23
    +

    As json::binary_t is subclassing std::vector<std::uint8_t>, 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 neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library.

    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<std::uint8t> 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_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 UBJSON has no binary type, and deserializing v would yield the following value:

    {
    +  "binary": [202, 254, 186, 190]
    +}
    +

    BSON

    BSON supports binary values and subtypes. If a subtype is given, it is used and added as 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<std::uint8t> 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 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<std::uint8t> 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 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 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<std::uint8t> 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 neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library.

    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<std::uint8t> 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]
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/comments/index.html b/features/comments/index.html new file mode 100644 index 000000000..0ca40f180 --- /dev/null +++ b/features/comments/index.html @@ -0,0 +1,53 @@ + Comments - JSON for Modern C++

    Comments

    This library does not support comments by default. It does so for three reasons:

    1. Comments are not part of the JSON specification. 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 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 would add comment support while others don't. Please check The Harmful Consequences of the Robustness Principle on this.

    However, you can pass set parameter ignore_comments to true in the parse function to ignore // or /* */ comments. Comments will then be treated as whitespace.

    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 <iostream>
    +#include "json.hpp"
    +
    +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: '<U+000A>    {<U+000A>        /'; expected string literal
    +
    {
    +  "planets": [
    +    "Mercury",
    +    "Venus",
    +    "Earth",
    +    "Mars",
    +    "Jupiter",
    +    "Uranus",
    +    "Neptune"
    +  ]
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/element_access/checked_access/index.html b/features/element_access/checked_access/index.html new file mode 100644 index 000000000..b53aefc83 --- /dev/null +++ b/features/element_access/checked_access/index.html @@ -0,0 +1,15 @@ + Checked access: at - JSON for Modern C++

    Checked access: at

    Overview

    The at 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 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 modified by 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 you 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

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/element_access/default_value/index.html b/features/element_access/default_value/index.html new file mode 100644 index 000000000..85cdc03d4 --- /dev/null +++ b/features/element_access/default_value/index.html @@ -0,0 +1,5 @@ + Access with default value: value - JSON for Modern C++

    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.

    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"

    Note

    Exceptions


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/element_access/index.html b/features/element_access/index.html new file mode 100644 index 000000000..ae95585a2 --- /dev/null +++ b/features/element_access/index.html @@ -0,0 +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

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/element_access/unchecked_access/index.html b/features/element_access/unchecked_access/index.html new file mode 100644 index 000000000..bc4ad1a37 --- /dev/null +++ b/features/element_access/unchecked_access/index.html @@ -0,0 +1,22 @@ + Unchecked access: operator[] - JSON for Modern C++

    Unchecked access: operator[]

    Overview

    Elements in a JSON object and a JSON array can be accessed via operator[] 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 be 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[] 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

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/enum_conversion/index.html b/features/enum_conversion/index.html new file mode 100644 index 000000000..99d66aedf --- /dev/null +++ b/features/enum_conversion/index.html @@ -0,0 +1,27 @@ + Specializing enum conversion - JSON for Modern C++

    Specializing enum 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 de-serialized JSON data may be undefined or a different enum value than was originally intended.

    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 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<TaskState>() == TS_RUNNING);
    +
    +// 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 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.

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/iterators/index.html b/features/iterators/index.html new file mode 100644 index 000000000..f0e7b5b21 --- /dev/null +++ b/features/iterators/index.html @@ -0,0 +1,56 @@ + Iterators - JSON for Modern C++

    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

    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 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 key 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 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 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

    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 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

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/json_patch/index.html b/features/json_patch/index.html new file mode 100644 index 000000000..14f89b7a0 --- /dev/null +++ b/features/json_patch/index.html @@ -0,0 +1,108 @@ + JSON Patch and Diff - JSON for Modern C++

    JSON Patch and Diff

    Patches

    JSON Patch (RFC 6902) 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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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"
    +    ]
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/json_pointer/index.html b/features/json_pointer/index.html new file mode 100644 index 000000000..948d296b4 --- /dev/null +++ b/features/json_pointer/index.html @@ -0,0 +1,48 @@ + JSON Pointer - JSON for Modern C++

    JSON Pointer

    Introduction

    The library supports JSON Pointer (RFC 6901) as 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 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 are implemented. See the constructor documentation for more information.

    Value access

    JSON Pointers can be used in the at, operator[], and value 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 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 recreates the original value.

    auto j_original = j_flat.unflatten();
    +

    See also


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/macros/index.html b/features/macros/index.html new file mode 100644 index 000000000..38b08fbec --- /dev/null +++ b/features/macros/index.html @@ -0,0 +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_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_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20

    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, and JSON_HAS_CPP_20.

    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 to use 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.

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)

    This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) 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, it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members.

    See full documentation of NLOHMANN_DEFINE_TYPE_INTRUSIVE.

    NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...)

    This macro is similar to NLOHMANN_DEFINE_TYPE_INTRUSIVE. It will not throw an exception in from_json() due to a missing value in the JSON object, but can throw due to a mismatched type. The from_json() function default constructs an object and uses its values as the defaults when calling the value function.

    See full documentation of NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT.

    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)

    This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object.

    The macro is to be defined inside the namespace of the class/struct to create code for. Private members cannot be accessed. Use NLOHMANN_DEFINE_TYPE_INTRUSIVE in these scenarios. The first parameter is the name of the class/struct, and all remaining parameters name the members.

    See full documentation of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE.

    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...)

    This macro is similar to NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE. It will not throw an exception in from_json() due to a missing value in the JSON object, but can throw due to a mismatched type. The from_json() function default constructs an object and uses its values as the defaults when calling the value function.

    See full documentation of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT.

    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.

    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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/merge_patch/index.html b/features/merge_patch/index.html new file mode 100644 index 000000000..887664650 --- /dev/null +++ b/features/merge_patch/index.html @@ -0,0 +1,53 @@ + JSON Merge Patch - JSON for Modern C++

    JSON Merge Patch

    The library supports JSON Merge Patch (RFC 7386) 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 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 <iostream>
    +#include <nlohmann/json.hpp>
    +#include <iomanip> // 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!"
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/namespace/index.html b/features/namespace/index.html new file mode 100644 index 000000000..c8ca8a4a0 --- /dev/null +++ b/features/namespace/index.html @@ -0,0 +1,4 @@ + nlohmann Namespace - JSON for Modern C++

    nlohmann Namespace

    The 3.11.0 release introduced an inline namespace 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 serveral optional ABI tags according to the value of these ABI-affecting macros, in order:
    • 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 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. This is illustrated in the diagram below.

    uml diagram

    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 linline 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.

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/object_order/index.html b/features/object_order/index.html new file mode 100644 index 000000000..3010e07e2 --- /dev/null +++ b/features/object_order/index.html @@ -0,0 +1,60 @@ + Object Order - JSON for Modern C++

    Object Order

    The JSON standard 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 <iostream>
    +#include "json.hpp"
    +
    +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 try the type nlohmann::ordered_json.

    Example
    #include <iostream>
    +#include <nlohmann/json.hpp>
    +
    +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 (integration) or nlohmann::fifo_map (integration).

    Notes on parsing

    Note that you also need to call the right parse 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,
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/parsing/index.html b/features/parsing/index.html new file mode 100644 index 000000000..f921b3677 --- /dev/null +++ b/features/parsing/index.html @@ -0,0 +1 @@ + Parsing - JSON for Modern C++
    \ No newline at end of file diff --git a/features/parsing/json_lines/index.html b/features/parsing/json_lines/index.html new file mode 100644 index 000000000..fbb322f43 --- /dev/null +++ b/features/parsing/json_lines/index.html @@ -0,0 +1,36 @@ + JSON Lines - JSON for Modern C++

    JSON Lines

    The JSON Lines 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.

    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 or accept functions. To process it line by line, functions like std::getline can be used:

    Example: Parse JSON Text input line by line

    The example below demonstrates how JSON Lines can be processed.

    #include <sstream>
    +#include <iostream>
    +#include <nlohmann/json.hpp>
    +
    +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>> 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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/parsing/parse_exceptions/index.html b/features/parsing/parse_exceptions/index.html new file mode 100644 index 000000000..0f3a756b7 --- /dev/null +++ b/features/parsing/parse_exceptions/index.html @@ -0,0 +1,66 @@ + Parsing and Exceptions - JSON for Modern C++

    Parsing and Exceptions

    When the input is not valid JSON, an exception of type parse_error 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. 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 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 <iostream>
    +#include "json.hpp"
    +
    +using json = nlohmann::json;
    +
    +class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
    +{
    +  public:
    +    sax_no_exception(json& j)
    +      : nlohmann::detail::json_sax_dom_parser<json>(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]
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/parsing/parser_callbacks/index.html b/features/parsing/parser_callbacks/index.html new file mode 100644 index 000000000..1fcb6d363 --- /dev/null +++ b/features/parsing/parser_callbacks/index.html @@ -0,0 +1,94 @@ + Parser Callbacks - JSON for Modern C++

    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<typename BasicJsonType>
    +using parser_callback_t =
    +    std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
    +

    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 <iostream>
    +#include <iomanip>
    +#include <nlohmann/json.hpp>
    +
    +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
    +    }
    +}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/parsing/sax_interface/index.html b/features/parsing/sax_interface/index.html new file mode 100644 index 000000000..d17bfceae --- /dev/null +++ b/features/parsing/sax_interface/index.html @@ -0,0 +1,29 @@ + SAX Interface - JSON for Modern C++

    SAX Interface

    The library uses a SAX-like interface with the following functions:

    uml diagram

    // 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& 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<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


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/types/index.html b/features/types/index.html new file mode 100644 index 000000000..0e2535ef7 --- /dev/null +++ b/features/types/index.html @@ -0,0 +1,39 @@ + Types - JSON for Modern C++

    Types

    This page gives an overview 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<std::string, basic_json>
    array std::vector<basic_json>
    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

    uml diagram

    Template arguments

    The data types to store a JSON value are derived from the template arguments passed to class basic_json:

    template<
    +    template<typename U, typename V, typename... Args> class ObjectType = std::map,
    +    template<typename U, typename... Args> 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<typename U> class AllocatorType = std::allocator,
    +    template<typename T, typename SFINAE = void> class JSONSerializer = adl_serializer,
    +    class BinaryType = std::vector<std::uint8_t>
    +>
    +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<StringType, basic_json, object_comparator_t,
    +                   AllocatorType<std::pair<const StringType, basic_json>>>;
    +
    +using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
    +
    +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<BinaryType>;
    +

    Objects

    RFC 8259 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<std::pair<const std::string, basic_json>> // 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 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, because any order implements the specified "unordered" nature of JSON objects.

    Limits

    RFC 8259 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 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<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 is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 be 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 be 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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/features/types/number_handling/index.html b/features/types/number_handling/index.html new file mode 100644 index 000000000..10df0f7a4 --- /dev/null +++ b/features/types/number_handling/index.html @@ -0,0 +1,57 @@ + Number Handling - JSON for Modern C++

    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, 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 visualizes the number syntax:

    Syntax for JSON numbers

    Number interoperability

    On number interoperability, the following remarks are made:

    RFC 8259, 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 the above number specification is implemented by this library.

    Number storage

    In the default json 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

    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 are not satisfying std::isfinite such as 1E400) will throw exception json.exception.out_of_range.406 during parsing.
    • Floating-point numbers are rounded to the next number representable as double. For instance 3.141592653589793238462643383279 is stored as 0x400921fb54442d18. This is the same behavior as the code double x = 3.141592653589793238462643383279;.

    Interoperability

    • The library 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<double>::max_digits10 significant digits. The rationale is to use the shortest representation while still allow 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<double>::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, 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, NaN values can be stored in a JSON value by assignment.

    This library serializes NaN values as null. This corresponds to the behavior of JavaScript's JSON.stringify function.

    Example

    The following example shows how a NaN value is stored in a json value.

    int main()
    +{
    +    double val = std::numeric_limits<double>::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 inside JSON values numbers 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 could be used, for instance

    template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
    +inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::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<float>::epsilon();
    +
    +            // other cases remain the same with the original
    +            ...
    +        }
    +    }
    +    ...
    +}
    +

    (see #703 for more information.)

    Note

    NaN values never compare equal to themselves or to other NaN values. See #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 to integers. 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<std::int64_t>();  // now i==42; no warning or error is produced
    +

    Note the last line with throw a json.exception.type_error.302 exception if jd is not a numerical type, for instance a string.

    The rationale is twofold:

    1. JSON does not define a number type or precision (see #json-specification).
    2. C++ also allows to silently convert 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() or is_number_unsigned():

    // 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<std::int64_t>();
    +    // ...
    +}
    +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.)

    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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/home/code_of_conduct/index.html b/home/code_of_conduct/index.html new file mode 100644 index 000000000..cc1f6681a --- /dev/null +++ b/home/code_of_conduct/index.html @@ -0,0 +1 @@ + Code of Conduct - JSON for Modern C++

    Contributor Covenant Code of Conduct

    Our Pledge

    In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

    Our Standards

    Examples of behavior that contributes to creating a positive environment include:

    • Using welcoming and inclusive language
    • Being respectful of differing viewpoints and experiences
    • Gracefully accepting constructive criticism
    • Focusing on what is best for the community
    • Showing empathy towards other community members

    Examples of unacceptable behavior by participants include:

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

    Our Responsibilities

    Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

    Project maintainers 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, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

    Scope

    This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

    Enforcement

    Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

    Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

    Attribution

    This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/home/design_goals/index.html b/home/design_goals/index.html new file mode 100644 index 000000000..ef8df883b --- /dev/null +++ b/home/design_goals/index.html @@ -0,0 +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. Check out the examples below, and you'll know what I mean.

    • 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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/home/exceptions/index.html b/home/exceptions/index.html new file mode 100644 index 000000000..28d04c18b --- /dev/null +++ b/home/exceptions/index.html @@ -0,0 +1,259 @@ + Exceptions - JSON for Modern C++

    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.

    uml diagram

    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. 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 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 <iostream>
    +
    +#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 <nlohmann/json.hpp>
    +

    Note the explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824.

    See documentation of JSON_TRY_USER, JSON_CATCH_USER and JSON_THROW_USER 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 <iostream>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    json j;
    +    j["address"]["street"] = "Fake Street";
    +    j["address"]["housenumber"] = "12";
    +
    +    try
    +    {
    +        int housenumber = j["address"]["housenumber"];
    +    }
    +    catch (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 lead to the exception) can be created. That global context is provided as JSON Pointer.

    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 to 1 before including json.hpp.

    Example
    #include <iostream>
    +
    +# define JSON_DIAGNOSTICS 1
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    json j;
    +    j["address"]["street"] = "Fake Street";
    +    j["address"]["housenumber"] = "12";
    +
    +    try
    +    {
    +        int housenumber = j["address"]["housenumber"];
    +    }
    +    catch (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 for more information.

    Parse errors

    This exception is thrown by the library 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 <iostream>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    try
    +    {
    +        // parsing input with a syntax error
    +        json::parse("[1,2,3,]");
    +    }
    +    catch (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: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
    +

    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: '"<U+0009>'"
    +

    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 http://jsonlint.com or a tool like 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 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 with a more detailed description is used.

    json.exception.parse_error.104

    RFC 6902 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) 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 or length information is invalid (BSON).

    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 <iostream>
    +#include <nlohmann/json.hpp>
    +
    +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 (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 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) 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 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 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 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.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 get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to 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 <iostream>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    try
    +    {
    +        // calling push_back() on a string value
    +        json j = "string";
    +        j.push_back("another string");
    +    }
    +    catch (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 to 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() 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 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 <iostream>
    +#include <nlohmann/json.hpp>
    +
    +using json = nlohmann::json;
    +
    +int main()
    +{
    +    try
    +    {
    +        // calling at() for an invalid index
    +        json j = {1, 2, 3, 4};
    +        j.at(4) = 10;
    +    }
    +    catch (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' can not 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

    UBJSON and BSON only support integer numbers up to 9223372036854775807.

    Example message

    number overflow serializing '9223372036854775808'
    +

    Note

    Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers, and this exception does not further occur.

    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)
    +

    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 <iostream>
    +#include <nlohmann/json.hpp>
    +
    +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 (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"}
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/home/faq/index.html b/home/faq/index.html new file mode 100644 index 000000000..a616f23da --- /dev/null +++ b/home/faq/index.html @@ -0,0 +1,29 @@ + FAQ - JSON for Modern C++

    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.

    Limitations

    Relaxed parsing

    Question

    Can you add an option to ignore trailing commas?

    This library does not support any feature which 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.
    • 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.
    • Unicode noncharacters will not be replaced by the library.
    • 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() 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, the library assumes UTF-8 as encoding. To store a wide string, you need to change the encoding.

    Example

    #include <codecvt> // codecvt_utf8
    +#include <locale>  // wstring_convert
    +
    +// encoding function
    +std::string to_utf8(std::wstring& wide_string)
    +{
    +    static std::wstring_convert<std::codecvt_utf8<wchar_t>> 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.

    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.

    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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/home/license/index.html b/home/license/index.html new file mode 100644 index 000000000..9c806423e --- /dev/null +++ b/home/license/index.html @@ -0,0 +1 @@ + License - JSON for Modern C++

    License

    The class is licensed under the MIT License:

    Copyright © 2013-2022 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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/home/releases/index.html b/home/releases/index.html new file mode 100644 index 000000000..a37f22d63 --- /dev/null +++ b/home/releases/index.html @@ -0,0 +1,10 @@ + Releases - JSON for Modern C++

    Releases

    v3.7.3

    Files

    Release date: 2019-11-17 SHA-256: 3b5d2b8f8282b80557091514d8ab97e27f9574336c804ee666fda673a9b59926 (json.hpp), 87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014 (include.zip)

    Summary

    This release fixes a bug introduced in release 3.7.2 which could yield quadratic complexity in destructor calls. All changes are backward-compatible.

    🐛 Bug Fixes

    • Removed reserve() calls from the destructor which could lead to quadratic complexity. #1837 #1838

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.7.2

    Files

    Release date: 2019-11-10 SHA-256: 0a65fcbbe1b334d3f45c9498e5ee28c3f3b2428aea98557da4a3ff12f0f14ad6 (json.hpp), 67f69c9a93b7fa0612dc1b6273119d2c560317333581845f358aaa68bff8f087 (include.zip)

    Summary

    Project bad_json_parsers tested how JSON parser libraries react on deeply nested inputs. It turns out that this library segfaulted at a certain nesting depth. This bug was fixed with this release. Now the parsing is only bounded by the available memory. All changes are backward-compatible.

    🐛 Bug Fixes

    • Fixed a bug that lead to stack overflow for deeply nested JSON values (objects, array) by changing the implementation of the destructor from a recursive to an iterative approach. #832, #1419, #1835

    🔨 Further Changes

    • Added WhiteStone Bolt. #1830

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.7.1

    Files

    Release date: 2019-11-06 SHA-256: b5ba7228f3c22a882d379e93d08eab4349458ee16fbf45291347994eac7dc7ce (json.hpp), 77b9f54b34e7989e6f402afb516f7ff2830df551c3a36973085e2c7a6b1045fe (include.zip)

    Summary

    This release fixes several small bugs in the library. All changes are backward-compatible.

    🐛 Bug Fixes

    • Fixed a segmentation fault when serializing std::int64_t minimum value. #1708 #1722
    • Fixed the contains() function for JSON Pointers. #1727 #1741
    • Fixed too lax SFINAE guard for conversion from std::pair and std::tuple to json. #1805 #1806 #1825 #1826
    • Fixed some regressions detected by UBSAN. Updated CI to use Clang-Tidy 7.1.0. #1716 #1728
    • Fixed integer truncation in iteration_proxy. #1797
    • Updated Hedley to v11 to fix a E2512 error in MSVC. #1799
    • Fixed a compile error in enum deserialization of non non-default-constructible types. #1647 #1821
    • Fixed the conversion from json to std::valarray.

    ⚡ Improvements

    • The items() function can now be used with a custom string type. #1765
    • Made json_pointer::back const. #1764 #1769
    • Meson is part of the release archive. #1672 #1694
    • Improved documentation on the Meson and Spack package manager. #1694 #1720

    🔨 Further Changes

    • Added GitHub Workflow with ubuntu-latest/GCC 7.4.0 as CI step.
    • Added GCC 9 to Travis CI to compile with C++20 support. #1724
    • Added MSVC 2019 to the AppVeyor CI. #1780
    • Added badge to fuzzing status.
    • Fixed some cppcheck warnings. #1760
    • Fixed several typos in the documentation. #1720 #1767 #1803
    • Added documentation on the JSON_THROW_USER, JSON_TRY_USER, and JSON_CATCH_USER macros to control user-defined exception handling.
    • Used GitHub's CODEOWNERS and SECURITY feature.
    • Removed GLOB from CMake files. #1779
    • Updated to Doctest 2.3.5.

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.7.0

    Files

    Release date: 2019-07-28 SHA-256: a503214947952b69f0062f572cb74c17582a495767446347ce2e452963fc2ca4 (json.hpp), 541c34438fd54182e9cdc68dd20c898d766713ad6d901fb2c6e28ff1f1e7c10d (include.zip)

    Summary

    This release introduces a few convenience functions and performs a lot of house keeping (bug fixes and small improvements). All changes are backward-compatible.

    ✨ New Features

    • Add overload of the contains function to check if a JSON pointer is valid without throwing exceptions, just like its counterpart for object keys. #1600
    • Add a function to_string to allow for generic conversion to strings. #916 #1585
    • Add return value for the emplace_back function, returning a reference to the added element just like C++17 is introducing this for std::vector. #1609
    • Add info how to use the library with the pacman package manager on MSYS2. #1670

    🐛 Bug Fixes

    • Fix an issue where typedefs with certain names yielded a compilation error. #1642 #1643
    • Fix a conversion to std::string_view in the unit tests. #1634 #1639
    • Fix MSVC Debug build. #1536 #1570 #1608
    • Fix get_to method to clear existing content before writing. #1511 #1555
    • Fix a -Wc++17-extensions warning. nodiscard attributes are now only used with Clang when -std=c++17 is used. #1535 #1551

    ⚡ Improvements

    🔨 Further Changes

    • Use GNUInstallDirs to set library install directories. #1673
    • Fix links in the README. #1620 #1621 #1622 #1623 #1625
    • Mention json type on the documentation start page. #1616
    • Complete documentation of value() function with respect to type_error.302 exception. #1601
    • Fix links in the documentation. #1598
    • Add regression tests for MSVC. #1543 #1570
    • Use CircleCI for continuous integration.
    • Use Doozer for continuous integration on Linux (CentOS, Raspbian, Fedora)
    • Add tests to check each CMake flag (JSON_BuildTests, JSON_Install, JSON_MultipleHeaders, JSON_Sanitizer, JSON_Valgrind, JSON_NoExceptions, JSON_Coverage).
    • Use Hedley to avoid re-inventing several compiler-agnostic feature macros like JSON_DEPRECATED, JSON_NODISCARD, JSON_LIKELY, JSON_UNLIKELY, JSON_HAS_CPP_14, or JSON_HAS_CPP_17. Functions taking or returning pointers are annotated accordingly when a pointer will not be null.
    • Build and run tests on AppVeyor in DEBUG and RELEASE mode.

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.6.1

    Files

    Release date: 2019-03-20 SHA-256: d2eeb25d2e95bffeb08ebb7704cdffd2e8fca7113eba9a0b38d60a5c391ea09a (json.hpp), 69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf (include.zip)

    Summary

    This release fixes a regression and a bug introduced by the earlier 3.6.0 release. All changes are backward-compatible.

    🐛 Bug Fixes

    • Fixed regression of #590 which could lead to compilation errors with GCC 7 and GCC 8. #1530
    • Fixed a compilation error when <Windows.h> was included. #1531

    🔨 Further Changes

    • Fixed a warning for missing field initializers. #1527

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.6.0

    Files

    Release date: 2019-03-20 SHA-256: ce9839370f28094c71107c405affb3b08c4a098154988014cbb0800b1c44a831 (json.hpp), 237c5e66e7f8186a02804ce9dbd5f69ce89fe7424ef84adf6142e973bd9532f4 (include.zip)

    ℹ️ This release introduced a regression. Please update to version 3.6.1!

    Summary

    This release adds some convenience functions for JSON Pointers, introduces a contains function to check if a key is present in an object, and improves the performance of integer serialization. Furthermore, a lot of small bug fixes and improvements have been made. All changes are backward-compatible.

    ✨ New Features

    • Overworked the public interface for JSON Pointers. The creation of JSON Pointers is simplified with operator/ and operator/=. JSON Pointers can be inspected with empty, back, and parent_pointer, and manipulated with push_back and pop_back. #1434
    • Added a boolean method contains to check whether an element exists in a JSON object with a given key. Returns false when called on non-object types. #1471 #1474

    🐛 Bug Fixes

    • Fixed a compilation issues with libc 2.12. #1483 #1514
    • Fixed endian conversion on PPC64. #1489
    • Fixed library to compile with GCC 9. #1472 #1492
    • Fixed a compilation issue with GCC 7 on CentOS. #1496
    • Fixed an integer overflow. #1447
    • Fixed buffer flushing in serializer. #1445 #1446

    ⚡ Improvements

    • The performance of dumping integers has been greatly improved. #1411
    • Added CMake parameter JSON_Install to control whether the library should be installed (default: on). #1330
    • Fixed a lot of compiler and linter warnings. #1400 #1435 #1502
    • Reduced required CMake version from 3.8 to 3.1. #1409 #1428 #1441 #1498
    • Added nodiscard attribute to meta(), array(), object(), from_cbor, from_msgpack, from_ubjson, from_bson, and parse. #1433

    🔨 Further Changes

    • Added missing headers. #1500
    • Fixed typos and broken links in README. #1417 #1423 #1425 #1451 #1455 #1491
    • Fixed documentation of parse function. #1473
    • Suppressed warning that cannot be fixed inside the library. #1401 #1468
    • Imroved package manager suppert:
      • Updated Buckaroo instructions. #1495
      • Improved Meson support. #1463
      • Added Conda package manager documentation. #1430
      • Added NuGet package manager documentation. #1132
    • Continuous Integration
      • Removed unstable or deprecated Travis builders (Xcode 6.4 - 8.2) and added Xcode 10.1 builder.
      • Added Clang 7 to Travis CI.
      • Fixed AppVeyor x64 builds. #1374 #1414
    • Updated thirdparty libraries:
      • Catch 1.12.0 -> 1.12.2
      • Google Benchmark 1.3.0 -> 1.4.1
      • Doxygen 1.8.15 -> 1.8.16

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.5.0

    Files

    Release date: 2018-12-22 SHA-256: 8a6dbf3bf01156f438d0ca7e78c2971bca50eec4ca6f0cf59adf3464c43bb9d5 (json.hpp), 3564da9c5b0cf2e032f97c69baedf10ddbc98030c337d0327a215ea72259ea21 (include.zip)

    Summary

    This release introduces the support for structured bindings and reading from FILE*. Besides, a few bugs have been fixed. All changes are backward-compatible.

    ✨ New Features

    • Structured bindings are now supported for JSON objects and arrays via the items() member function, so finally this code is possible:

      for (auto& [key, val] : j.items()) {
      +    std::cout << key << ':' << val << '\n';
      +}
      +
      #1388 #1391

    • Added support for reading from FILE* to support situations in which streams are nit available or would require too much RAM. #1370 #1392

    🐛 Bug Fixes

    • The eofbit was not set for input streams when the end of a stream was reached while parsing. #1340 #1343
    • Fixed a bug in the SAX parser for BSON arrays.

    ⚡ Improvements

    • Added support for Clang 5.0.1 (PS4 version). #1341 #1342

    🔨 Further Changes

    • Added a warning for implicit conversions to the documentation: It is not recommended to use implicit conversions when reading from a JSON value. Details about this recommendation can be found here. #1363
    • Fixed typos in the documentation. #1329 #1380 #1382
    • Fixed a C4800 warning. #1364
    • Fixed a -Wshadow warning #1346
    • Wrapped std::snprintf calls to avoid error in MSVC. #1337
    • Added code to allow installation via Meson. #1345

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.4.0

    Files

    Release date: 2018-10-30 SHA-256: 63da6d1f22b2a7bb9e4ff7d6b255cf691a161ff49532dcc45d398a53e295835f (json.hpp), bfec46fc0cee01c509cf064d2254517e7fa80d1e7647fea37cf81d97c5682bdc (include.zip)

    Summary

    This release introduces three new features:

    • BSON (Binary JSON) is next to CBOR, MessagePack, and UBJSON the fourth binary (de)serialization format supported by the library.
    • Adjustable error handlers for invalid Unicode allows to specify the behavior when invalid byte sequences are serialized.
    • Simplified enum/JSON mapping with a macro in case the default mapping to integers is not desired.

    Furthermore, some effort has been invested in improving the parse error messages. Besides, a few bugs have been fixed. All changes are backward-compatible.

    ✨ New Features

    • The library can read and write a subset of BSON (Binary JSON). All data types known from JSON are supported, whereas other types more tied to MongoDB such as timestamps, object ids, or binary data are currently not implemented. See the README for examples. #1244 #1320
    • The behavior when the library encounters an invalid Unicode sequence during serialization can now be controlled by defining one of three Unicode error handlers: (1) throw an exception (default behavior), (2) replace invalid sequences by the Unicode replacement character (U+FFFD), or (3) ignore/filter invalid sequences. See the documentation of the dump function for examples. #1198 #1314
    • To easily specify a user-defined enum/JSON mapping, a macro NLOHMANN_JSON_SERIALIZE_ENUM has been introduced. See the README section for more information. #1208 #1323

    🐛 Bug Fixes

    • fixed truncation #1286 #1315
    • fixed an issue with std::pair #1299 #1301
    • fixed an issue with std::variant #1292 #1294
    • fixed a bug in the JSON Pointer parser

    ⚡ Improvements

    • The diagnosis messages for parse errors have been improved: error messages now indicated line/column positions where possible (in addition to a byte count) and also the context in which the error occurred (e.g., "while parsing a JSON string"). Example: error parse error at 2: syntax error - invalid string: control character must be escaped; last read: '<U+0009>' is now reported as 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 \t; last read: '<U+0009>'. #1280 #1288 #1303

    🔨 Further Changes

    • improved Meson documentation #1305
    • fixed some more linter warnings #1280
    • fixed Clang detection for third-party Google Benchmark library #1277

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.3.0

    Files

    Release date: 2018-10-05 SHA-256: f1327bb60c58757a3dd2b0c9c45d49503d571337681d950ec621f8374bcc14d4 (json.hpp), 9588d63557333aaa485e92221ec38014a85a6134e7486fe3441e0541a5a89576 (include.zip)

    Summary

    This release adds support for GCC 4.8. Furthermore, it adds a function get_to to write a JSON value to a passed reference. Another topic of this release was the CMake support which has been overworked and documented.

    Besides, a lot of bugs have been fixed and slight improvements have been made. All changes are backward-compatible.

    ✨ New Features

    • The library can now also built with GCC 4.8. Though this compiler does not fully support C++11, it can successfully compile and run the test suite. Note that bug 57824 in GCC 4.8 still forbids to use multiline raw strings in arguments to macros. #1257
    • Added new function get_to to write a JSON value to a passed reference. The destination type is automatically derived which allows more succinct code compared to the get function. #1227 #1231

    🐛 Bug Fixes

    • Fixed a bug in the CMake file that made target_link_libraries to not properly include nlohmann_json. #1243 #1245 #1260
    • Fixed a warning in MSVC 2017 complaining about a constexpr if. #1204 #1268 #1272
    • Fixed a bug that prevented compilation with ICPC. #755 #1222
    • Improved the SFINAE correctness to fix a bug in the conversion operator. #1237 #1238
    • Fixed a -Wctor-dtor-privacy warning. #1224
    • Fixed a warning on a lambda in unevaluated context. #1225 #1230
    • Fixed a bug introduced in version 3.2.0 where defining JSON_CATCH_USER led to duplicate macro definition of JSON_INTERNAL_CATCH. #1213 #1214
    • Fixed a bug that prevented compilation with Clang 3.4.2 in RHEL 7. #1179 #1249

    ⚡ Improvements

    • Added documentation on CMake integration of the library. #1270
    • Changed the CMake file to use find_package(nlohmann_json) without installing the library. #1202
    • Improved error messages in case operator[] is used with the wrong combination (json.exception.type_error.305) of JSON container type and argument type. Example: "cannot use operator[] with a string argument". #1220 #1221
    • Added a license and version information to the Meson build file. #1252
    • Removed static assertions to indicated missing to_json or from_json functions as such assertions do not play well with SFINAE. These assertions also led to problems with GMock. #960 #1212 #1228
    • The test suite now does not wait forever if run in a wrong directory and input files are not found. #1262
    • The test suite does not show deprecation warnings for deprecated functions which frequently led to confusion. #1271

    🔨 Further Changes

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.2.0

    Files

    Release date: 2018-08-20 SHA-256: ce6b5610a051ec6795fa11c33854abebb086f0fd67c311f5921c3c07f9531b44 (json.hpp), 35ee642558b90e2f9bc758995c4788c4b4d4dec54eef95fb8f38cb4d49c8fc7c (include.zip)

    Summary

    This release introduces a SAX interface to the library. While this may be a very special feature used by only few people, it allowed to unify all functions that consumed input and created some kind of JSON value. Internally, now all existing functions like parse, accept, from_cbor, from_msgpack, and from_ubjson use the SAX interface with different event processors. This allowed to separate the input processing from the value generation. Furthermore, throwing an exception in case of a parse error is now optional and up to the event processor. Finally, the JSON parser is now non-recursive (meaning it does not use the call stack, but std::vector<bool> to track the hierarchy of structured values) which allows to process nested input more efficiently.

    Furthermore, the library finally is able to parse from wide string types. This is the first step toward opening the library from UTF-8 to UTF-16 and UTF-32.

    This release further fixes several bugs in the library. All changes are backward-compatible.

    ✨ New Features

    • added a parser with a SAX interface (#971, #1153)
    • support to parse from wide string types std::wstring, std::u16string, and std::u32string; the input will be converted to UTF-8 (#1031)
    • added support for std::string_view when using C++17 (#1028)
    • allow to roundtrip std::map and std::unordered_map from JSON if key type is not convertible to string; in these cases, values are serialized to arrays of pairs (#1079, #1089, #1133, #1138)

    🐛 Bug Fixes

    • allow to create nullptr_t from JSON allowing to properly roundtrip null values (#1169)
    • allow compare user-defined string types (#1130)
    • better support for algorithms using iterators from items() (#1045, #1134)
    • added parameter to avoid compilation error with MSVC 2015 debug builds (#1114)
    • re-added accidentally skipped unit tests (#1176)
    • fixed MSVC issue with std::swap (#1168)

    ⚡ Improvements

    • key() function for iterators returns a const reference rather than a string copy (#1098)
    • binary formats CBOR, MessagePack, and UBJSON now supports float as type for floating-point numbers (#1021)

    🔨 Further Changes

    • changed issue templates
    • improved continuous integration: added builders for Xcode 9.3 and 9.4, added builders for GCC 8 and Clang 6, added builder for MinGW, added builders for MSVC targeting x86
    • required CMake version is now at least 3.8 (#1040)
    • overworked CMake file wrt. packaging (#1048)
    • added package managers: Spack (#1041) and CocoaPods (#1148)
    • fixed Meson include directory (#1142)
    • preprocessor macro JSON_SKIP_UNSUPPORTED_COMPILER_CHECK can skip the rejection of unsupported compilers - use at your own risk! (#1128)
    • preprocessor macro JSON_INTERNAL_CATCH/JSON_INTERNAL_CATCH_USER allows to control the behavior of exception handling inside the library (#1187)
    • added note on char to JSON conversion
    • added note how to send security-related issue via encrypted email
    • removed dependency to std::stringstream (#1117)
    • added SPDX-License-Identifier
    • added updated JSON Parsing Test Suite, described in Parsing JSON is a Minefield 💣
    • updated to Catch 1.12.0

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.1.2

    Files

    Release date: 2018-03-14 SHA-256: fbdfec4b4cf63b3b565d09f87e6c3c183bdd45c5be1864d3fcb338f6f02c1733 (json.hpp), 495362ee1b9d03d9526ba9ccf1b4a9c37691abe3a642ddbced13e5778c16660c (include.zip)

    Summary

    This release fixes several bugs in the library. All changes are backward-compatible.

    🐛 Bug Fixes

    • Fixed a memory leak occurring in the parser callback (#1001).
    • Different specializations of basic_json (e.g., using different template arguments for strings or objects) can now be used in assignments (#972, #977, #986).
    • Fixed a logical error in an iterator range check (#992).

    ⚡ Improvements

    • The parser and the serialization now support user-defined string types (#1006, #1009).

    🔨 Further Changes

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.1.1

    Files

    Release date: 2018-02-13 SHA-256: e14ce5e33d6a2daf748026bd4947f3d9686ca4cfd53d10c3da46a0a9aceb7f2e (json.hpp), fde771d4b9e4f222965c00758a2bdd627d04fb7b59e09b7f3d1965abdc848505 (include.zip)

    Summary

    This release fixes several bugs in the library. All changes are backward-compatible.

    🐛 Bug Fixes

    • Fixed parsing of CBOR strings with indefinite length (#961). Earlier versions of this library misinterpreted the CBOR standard and rejected input with the 0x7F start byte.
    • Fixed user-defined conversion to vector type (#924, #969). A wrong SFINAE check rejected code though a user-defined conversion was provided.
    • Fixed documentation of the parser behavior for objects with duplicate keys (#963). The exact behavior is not specified by RFC 8259 and the library now also provides no guarantee which object key is stored.
    • Added check to detect memory overflow when parsing UBJSON containers (#962). The optimized UBJSON format allowed for specifying an array with billions of null elements with a few bytes and the library did not check whether this size exceeded max_size().

    🔨 Further Changes

    • Code coverage is now calculated for the individual header files, allowing to find uncovered lines more quickly than by browsing through the single header version (#953, #957).
    • A Makefile target run_benchmarks was added to quickly build and run the benchmark suite.
    • The documentation was harmonized with respect to the header inclusion (#955). Now all examples and the README use #include <nlohmann/json.hpp> to allow for selecting single_include or include or whatever installation folder as include directory.
    • Added note on how to use the library with the cget package manager (#954).

    🔥 Deprecated functions

    This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0):

    v3.1.0

    Files

    Release date: 2018-02-01 SHA-256: d40f614d10a6e4e4e80dca9463da905285f20e93116c36d97d4dc1aa63d10ba4 (json.hpp), 2b7234fca394d1e27b7e017117ed80b7518fafbb4f4c13a7c069624f6f924673 (include.zip)

    Summary

    This release adds support for the UBJSON format and JSON Merge Patch. It also contains some minor changes and bug fixes. All changes are backward-compatible.

    ✨ New features

    • The library now supports UBJSON (Universal Binary JSON Specification) as binary format to read and write JSON values space-efficiently. See the documentation overview for a comparison of the different formats CBOR, MessagePack, and UBJSON.
    • JSON Merge Patch (RFC 7386) offers an intuitive means to describe patches between JSON values (#876, #877). See the documentation of merge_patch for more information.

    ⚡ Improvements

    • The library now uses the Grisu2 algorithm for printing floating-point numbers (based on the reference implementation by Florian Loitsch) which produces a short representation which is guaranteed to round-trip (#360, #935, #936).
    • The UTF-8 handling was further simplified by using the decoder of Björn Hoehrmann in more scenarios.

    🚚 Reorganization

    • Though the library is released as a single header, its development got more and more complicated. With this release, the header is split into several files and the single-header file json.hpp can be generated from these development sources. In the repository, folder include contains the development sources and single_include contains the single json.hpp header (#700, #906, #907, #910, #911, #915, #920, #924, #925, #928, #944).
    • The split further allowed for a forward declaration header include/nlohmann/json_fwd.hpp to speed up compilation times (#314).

    🔨 Further changes

    • Google Benchmark is now used for micro benchmarks (see benchmarks folder, #921).
    • The serialization (JSON and binary formats) now properly work with the libraries string template parameter, allowing for optimized string implementations to be used in constraint environments such as embedded software (#941, #950).
    • The exceptional behavior can now be overridden by defining macros JSON_THROW_USER, JSON_TRY_USER, and JSON_CATCH_USER, defining the behavior of throw, try and catch, respectively. This allows to switch off C++'s exception mechanism yet still execute user-defined code in case an error condition occurs (#938).
    • To facilitate the interplay with flex and Bison, the library does not use the variable name yytext any more as it could clash with macro definitions (#933).
    • The library now defines NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, and NLOHMANN_JSON_VERSION_PATCH to allow for conditional compilation based on the included library version (#943, #948).
    • A compilation error with ICC has been fixed (#947).
    • Typos and links in the documentation have been fixed (#900, #930).
    • A compiler error related to incomplete types has been fixed (#919).
    • The tests form the UTF-8 decoder stress test have been added to the test suite.

    🔥 Deprecated functions

    • Function iterator_wrapper has been deprecated (#874). Since its introduction, the name was up for discussion, as it was too technical. We now introduced the member function items() with the same semantics. iterator_wrapper will be removed in the next major version (i.e., 4.0.0).

    Furthermore, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0):

    Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.

    v3.0.1

    Files

    Release date: 2017-12-29 SHA-256: c9b3591f1bb94e723a0cd7be861733a3a555b234ef132be1e9027a0364118c4c

    Summary

    This release fixes small issues in the implementation of JSON Pointer and JSON Patch. All changes are backward-compatible.

    Changes

    • 🐛 The "copy" operation of JSON Patch (RFC 6902) requests that it is an error if the target path points into a non-existing array or object (see #894 for a detailed description). This release fixes the implementation to detect such invalid target paths and throw an exception.
    • 🐛 An array index in a JSON Pointer (RFC 6901) must be an integer. This release fixes the implementation to throw an exception in case invalid array indices such as 10e2 are used.
    • ✅ Added the JSON Patch tests from Byron Ruth and Mike McCabe.
    • 📝 Fixed the documentation of the at(ptr) function with JSON Pointers to list all possible exceptions (see #888).
    • 📝 Updated the container overview documentation (see #883).
    • 🔧 The CMake files now respect the BUILD_TESTING option (see #846, #885)
    • 🚨 Fixed some compiler warnings (see #858, #882).

    Deprecated functions

    🔥 To unify the interfaces and to improve similarity with the STL, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0):

    Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.

    v3.0.0

    Files

    Release date: 2017-12-17 SHA-256: 076d4a0cb890a3c3d389c68421a11c3d77c64bd788e85d50f1b77ed252f2a462

    Summary

    After almost a year, here is finally a new release of JSON for Modern C++, and it is a major one! As we adhere to semantic versioning, this means the release includes some breaking changes, so please read the next section carefully before you update. But don't worry, we also added a few new features and put a lot of effort into fixing a lot of bugs and straighten out a few inconsistencies.

    💥 Breaking changes

    This section describes changes that change the public API of the library and may require changes in code using a previous version of the library. In section "Moving from 2.x.x to 3.0.0" at the end of the release notes, we describe in detail how existing code needs to be changed.

    • The library now uses user-defined exceptions instead of re-using those defined in <stdexcept> (#244). This not only allows to add more information to the exceptions (every exception now has an identifier, and parse errors contain the position of the error), but also to easily catch all library exceptions with a single catch(json::exception).
    • When strings with a different encoding as UTF-8 were stored in JSON values, their serialization could not be parsed by the library itself, as only UTF-8 is supported. To enforce this library limitation and improve consistency, non-UTF-8 encoded strings now yield a json::type_error exception during serialization (#838). The check for valid UTF-8 is realized with code from Björn Hoehrmann.
    • NaN and infinity values can now be stored inside the JSON value without throwing an exception. They are, however, still serialized as null (#388).
    • The library's iterator tag was changed from RandomAccessIterator to BidirectionalIterator (#593). Supporting RandomAccessIterator was incorrect as it assumed an ordering of values in a JSON objects which are unordered by definition.
    • The library does not include the standard headers <iostream>, <ctype>, and <stdexcept> any more. You may need to add these headers to code relying on them.
    • Removed constructor explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr) which was deprecated in version 2.0.0 (#480).

    🔥 Deprecated functions

    To unify the interfaces and to improve similarity with the STL, the following functions are now deprecated and will be removed in the next major version (i.e., 4.0.0):

    Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.

    ✨ New features

    With all this breaking and deprecation out of the way, let's talk about features!

    • We improved the diagnostic information for syntax errors (#301). Now, an exception json::parse_error is thrown which contains a detailed message on the error, but also a member byte to indicate the byte offset in the input where the error occurred.
    • We added a non-throwing syntax check (#458): The new accept function returns a Boolean indicating whether the input is proper JSON. We also added a Boolean parameter allow_exceptions to the existing parse functions to return a discarded value in case a syntax error occurs instead of throwing an exception.
    • An update function was added to merge two JSON objects (#428). In case you are wondering: the name was inspired by Python.
    • The insert function now also supports an iterator range to add elements to an object.
    • The binary exchange formats CBOR and MessagePack can now be parsed from input streams and written to output streams (#477).
    • Input streams are now only read until the end of a JSON value instead of the end of the input (#367).
    • The serialization function dump now has two optional parameters ensure_ascii to escape all non-ASCII characters with \uxxxx and an indent_char parameter to choose whether to indent with spaces or tabs (#654).
    • Added built-in type support for C arrays (#502), std::pair and std::tuple (#563, #614), enum and enum class (#545), std::vector<bool> (#494). Fixed support for std::valarray (#702), std::array (#553), and std::map<std::string, std::string> (#600, #607).

    🔨 Further changes

    Furthermore, there have been a lot of changes under the hood:

    • Replaced the re2c generated scanner by a self-coded version which allows for a better modularization of the parser and better diagnostics. To test the new scanner, we added millions (8,860,608 to be exact) of unit tests to check all valid and invalid byte sequences of the Unicode standard.
    • Google's OSS-Fuzz is still constantly fuzz-testing the library and found several issues that were fixed in this release (#497, #504, #514, #516, #518, #519, #575).
    • We now also ignore UTF-8 byte order marks when parsing from an iterator range (#602).
    • Values can be now moved from initializer lists (#663).
    • Updated to Catch 1.9.7. Unfortunately, Catch2 currently has some performance issues.
    • The non-exceptional paths of the library are now annotated with __builtin_expect to optimize branch prediction as long as no error occurs.
    • MSVC now produces a stack trace in MSVC if a from_json or to_json function was not found for a user-defined type. We also added a debug visualizer nlohmann_json.natvis for better debugging in MSVC (#844).
    • Overworked the documentation and added even more examples.
    • The build workflow now relies on CMake and CTest. Special flags can be chosen with CMake, including coverage (JSON_Coverage), compilation without exceptions (JSON_NoExceptions), LLVM sanitizers (JSON_Sanitizer), or execution with Valgrind (JSON_Valgrind).
    • Added support for package managers Meson (#576), Conan (#566), Hunter (#671, #829), and vcpkg (#753).
    • Added CI builders: Xcode 8.3, 9.0, 9.1, and 9.2; GCC 7.2; Clang 3.8, 3.9, 4.0, and 5.0; Visual Studio 2017. The library is further built with C++17 settings on the latest Clang, GCC, and MSVC version to quickly detect new issues.

    Moving from 2.x.x to 3.0.0

    User-defined Exceptions

    There are five different exceptions inheriting from json::exception:

    To support these exception, the try/catch blocks of your code need to be adjusted:

    new exception previous exception
    parse_error.101 invalid_argument
    parse_error.102 invalid_argument
    parse_error.103 invalid_argument
    parse_error.104 invalid_argument
    parse_error.105 invalid_argument
    parse_error.106 domain_error
    parse_error.107 domain_error
    parse_error.108 domain_error
    parse_error.109 invalid_argument
    parse_error.110 out_of_range
    parse_error.111 invalid_argument
    parse_error.112 invalid_argument
    invalid_iterator.201 domain_error
    invalid_iterator.202 domain_error
    invalid_iterator.203 domain_error
    invalid_iterator.204 out_of_range
    invalid_iterator.205 out_of_range
    invalid_iterator.206 domain_error
    invalid_iterator.207 domain_error
    invalid_iterator.208 domain_error
    invalid_iterator.209 domain_error
    invalid_iterator.210 domain_error
    invalid_iterator.211 domain_error
    invalid_iterator.212 domain_error
    invalid_iterator.213 domain_error
    invalid_iterator.214 out_of_range
    type_error.301 domain_error
    type_error.302 domain_error
    type_error.303 domain_error
    type_error.304 domain_error
    type_error.305 domain_error
    type_error.306 domain_error
    type_error.307 domain_error
    type_error.308 domain_error
    type_error.309 domain_error
    type_error.310 domain_error
    type_error.311 domain_error
    type_error.313 domain_error
    type_error.314 domain_error
    type_error.315 domain_error
    out_of_range.401 out_of_range
    out_of_range.402 out_of_range
    out_of_range.403 out_of_range
    out_of_range.404 out_of_range
    out_of_range.405 domain_error
    other_error.501 domain_error

    Handling of NaN and INF

    • If an overflow occurs during parsing a number from a JSON text, an exception json::out_of_range is thrown so that the overflow is detected early and roundtripping is guaranteed.

    • NaN and INF floating-point values can be stored in a JSON value and are not replaced by null. That is, the basic_json class behaves like double in this regard (no exception occurs). However, NaN and INF are serialized to null.

    Removal of deprecated functions

    Function explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr) should be replaced by the parse function: Let ss be a stream and cb be a parse callback function.

    Old code:

    json j(ss, cb);
    +

    New code:

    json j = json::parse(ss, cb);
    +

    If no callback function is used, also the following code works:

    json j;
    +j << ss;
    +

    or

    json j;
    +ss >> j;
    +

    v2.1.1

    Files

    Release date: 2017-02-25 SHA-256: faa2321beb1aa7416d035e7417fcfa59692ac3d8c202728f9bcc302e2d558f57

    Summary

    This release fixes a locale-related bug in the parser. To do so, the whole number handling (lexer, parser, and also the serialization) have been overworked. Furthermore, a lot of small changes added up that were added to this release. All changes are backward-compatible.

    Changes

    • 🐛 Locales that have a different character than . as decimal separator (e.g., the Norwegian locale nb_NO.UTF-8) led to truncated number parsing or parse errors. The library now has been fixed to work with any locale. Note that . is still the only valid decimal separator for JSON input.
    • 🐛 Numbers like 1.0 were correctly parsed as floating-point number, but serialized as integer (1). Now, floating-point numbers correctly round trip.
    • 🐛 Parsing incorrect JSON numbers with leading 0 (0123) could yield a buffer overflow. This is fixed now by detecting such errors directly by the lexer.
    • 🐛 Constructing a JSON value from a pointer was incorrectly interpreted as a Boolean; such code will now yield a compiler error.
    • 🐛 Comparing a JSON number with 0 led to a comparison with null. This is fixed now.
    • 🐛 All throw calls are now wrapped in macros.
    • 🔒 Starting during the preparation of this release (since 8 February 2017), commits and released files are cryptographically signed with this GPG key. Previous releases have also been signed.
    • ✨ The parser for MessagePack and CBOR now supports an optional start index parameter to define a byte offset for the parser.
    • 🚨 Some more warnings have been fixed. With Clang, the code compiles without warnings with -Weverything (well, it needs -Wno-documentation-unknown-command and -Wno-deprecated-declarations, but you get the point).
    • 🔨 The code can be compiled easier with many Android NDKs by avoiding macros like UINT8_MAX which previously required defining a preprocessor macro for compilation.
    • ⚡ The unit tests now compile two times faster.
    • ➕ Cotire is used to speed up the build.
    • ✏ Fixed a lot of typos in the documentation.
    • 📝 Added a section to the README file that lists all used third-party code/tools.
    • 📝 Added a note on constructing a string value vs. parsing.
    • ✅ The test suite now contains 11202597 unit tests.
    • 📝 Improved the Doxygen documentation by shortening the template parameters of class basic_json.
    • 👷 Removed Doozer.
    • 👷 Added Codacity.
    • ⬆ Upgraded Catch to version 1.7.2.

    v2.1.0

    Files

    • Release date: 2017-01-28
    • SHA-256: a571dee92515b685784fd527e38405cf3f5e13e96edbfe3f03d6df2e363a767b

    Summary

    This release introduces a means to convert from/to user-defined types. The release is backwards compatible.

    conversion

    Changes

    • ✨ The library now offers an elegant way to convert from and to arbitrary value types. All you need to do is to implement two functions: to_json and from_json. Then, a conversion is as simple as putting a = between variables. See the README for more information and examples.
    • ✨ Exceptions can now be switched off. This can be done by defining the preprocessor symbol JSON_NOEXCEPTION or by passing -fno-exceptions to your compiler. In case the code would usually thrown an exception, abort() is now called.
    • ✨ Information on the library can be queried with the new (static) function meta() which returns a JSON object with information on the version, compiler, and platform. See the documentation for an example.
    • 🐛 A bug in the CBOR parser was fixed which led to a buffer overflow.
    • ✨ The function type_name() is now public. It allows to query the type of a JSON value as string.
    • ✅ Added the Big List of Naughty Strings as test case.
    • ⬆ Updated to Catch v1.6.0.
    • 📝 Some typos in the documentation have been fixed.

    v2.0.10

    Files

    • Release date: 2017-01-02
    • SHA-256: ec27d4e74e9ce0f78066389a70724afd07f10761009322dc020656704ad5296d

    Summary

    This release fixes several security-relevant bugs in the MessagePack and CBOR parsers. The fixes are backwards compatible.

    Changes

    • 🐛 Fixed a lot of bugs in the CBOR and MesssagePack parsers. These bugs occurred if invalid input was parsed and then could lead in buffer overflows. These bugs were found with Google's OSS-Fuzz, see #405, #407, #408, #409, #411, and #412 for more information.
    • 👷 We now also use the Doozer continuous integration platform.
    • 👷 The complete test suite is now also run with Clang's address sanitizer and undefined-behavior sanitizer.
    • ✅ Overworked fuzz testing; CBOR and MessagePack implementations are now fuzz-tested. Furthermore, all fuzz tests now include a round trip which ensures created output can again be properly parsed and yields the same JSON value.
    • 📝 Clarified documentation of find() function to always return end() when called on non-object value types.
    • 🔨 Moved thirdparty test code to test/thirdparty directory.

    v2.0.9

    Files

    • Release date: 2016-12-16
    • SHA-256: fbf3396f13e187d6c214c297bddc742d918ea9b55e10bfb3d9f458b9bfdc22e5

    Summary

    This release implements with CBOR and MessagePack two binary serialization/deserialization formats. It further contains some small fixes and improvements. The fixes are backwards compatible.

    cbor

    Changes

    • ✨ The library can now read and write the binary formats CBOR (Concise Binary Object Representation) and MessagePack. Both formats are aimed to produce a very compact representation of JSON which can be parsed very efficiently. See the README file for more information and examples.
    • 🔥 simplified the iteration implementation allowing to remove dozens of lines of code
    • 🐛 fixed an integer overflow error detected by Google's OSS-Fuzz
    • 🐛 suppressed documentation warnings inside the library to facilitate compilation with -Wdocumentation
    • 🐛 fixed an overflow detection error in the number parser
    • 📝 updated contribution guidelines to a list of frequentely asked features that will most likely be never added to the library
    • 📝 added a table of contents to the README file to add some structure
    • 📝 mentioned the many examples and the documentation in the README file
    • 🔨 split unit tests into individual independent binaries to speed up compilation and testing
    • ✅ the test suite now contains 11201886 tests

    v2.0.8

    Files

    • Release date: 2016-12-02
    • SHA-256: b70db0ad34f8e0e61dc3f0cbab88099336c9674c193d8a3439d93d6aca2d7120

    Summary

    This release combines a lot of small fixes and improvements. The fixes are backwards compatible.

    Changes

    • 🐛 fixed a bug that froze the parser if a passed file was not found (now, std::invalid_argument is thrown)
    • 🐛 fixed a bug that lead to an error of a file at EOF was parsed again (now, std::invalid_argument is thrown)
    • ✨ the well known functions emplace and emplace_back have been added to JSON values and work as expected
    • ⚡ improved the performance of the serialization (dump function)
    • ⚡ improved the performance of the deserialization (parser)
    • 👷 some continuous integration images at Travis were added and retired; see here for the current continuous integration setup
    • 👷 the Coverity scan works again
    • 📈 the benchmarking code has been improved to produce more stable results
    • 📝 the README file has been extended and includes more frequently asked examples
    • ✅ the test suite now contains 8905518 tests
    • ⬆ updated Catch to version 1.5.8

    v2.0.7

    Files

    • Release date: 2016-11-02
    • SHA-256: 5545c323670f8165bae90b9dc6078825e86ec310d96cc4e5b47233ea43715bbf

    Summary

    This release fixes a few bugs in the JSON parser found in the Parsing JSON is a Minefield 💣 article. The fixes are backwards compatible.

    Changes

    • The article Parsing JSON is a Minefield 💣 discusses a lot of pitfalls of the JSON specification. When investigating the published test cases, a few bugs in the library were found and fixed:
    • Files with less than 5 bytes can now be parsed without error.
    • The library now properly rejects any file encoding other than UTF-8. Furthermore, incorrect surrogate pairs are properly detected and rejected.
    • The library now accepts all but one "yes" test (y_string_utf16.json): UTF-16 is not supported.
    • The library rejects all but one "no" test (n_number_then_00.json): Null bytes are treated as end of file instead of an error. This allows to parse input from null-terminated strings.
    • The string length passed to a user-defined string literal is now exploited to choose a more efficient constructor.
    • A few grammar mistakes in the README file have been fixed.

    v2.0.6

    Files

    • Release date: 2016-10-15
    • SHA256: 459cc93d5e2f503e50c6d5876eb86bfea7daf405f5a567c5a2c9abc2383756ae

    Summary

    This release fixes the semantics of operator[] for JSON Pointers (see below). This fix is backwards compatible.

    Changes

    • operator[] for JSON Pointers now behaves like the other versions of operator[] and transforms null values into objects or arrays if required. This allows to created nested structures like j["/foo/bar/2"] = 17 (yielding {"foo": "bar": [null, null, 17]}) without problems.
    • overworked a helper SFINAE function
    • fixed some documentation issues
    • fixed the CMake files to allow to run the test suite outside the main project directory
    • restored test coverage to 100%.

    v2.0.5

    Files

    • Release date: 2016-09-14
    • SHA-256: 8b7565263a44e2b7d3b89808bc73d2d639037ff0c1f379e3d56dbd77e00b98d9

    Summary

    This release fixes a regression bug in the stream parser (function parse() and the <</>> operators). This fix is backwards compatible.

    Changes

    • Bug fix: The end of a file stream was not detected properly which led to parse errors. This bug should have been fixed with 2.0.4, but there was still a flaw in the code.

    v2.0.4

    Files

    • Release date: 2016-09-11
    • SHA-256: 632ceec4c25c4e2153f71470d3a2b992c8355f6d8b4d627d05dd16095cd3aeda

    Summary

    This release fixes a bug in the stream parser (function parse() and the <</>> operators). This fix is backwards compatible.

    Changes

    • Bug fix: The end of a file stream was not detected properly which led to parse errors.
    • Fixed a compiler warning about an unused variable.

    v2.0.3

    Files

    • Release date: 2016-08-31
    • SHA-256: 535b73efe5546fde9e763c14aeadfc7b58183c0b3cd43c29741025aba6cf6bd3

    Summary

    This release combines a lot of small fixes and improvements. The release is backwards compatible.

    Changes

    • The parser/deserialization functions have been generalized to process any contiguous sequence of 1-byte elements (e.g., char, unsigned char, uint8_t). This includes all kind of string representations (string literals, char arrays, std::string, const char*), contiguous containers (C-style arrays, std::vector, std::array, std::valarray, std::initializer_list). User-defined containers providing random-access iterator access via std::begin and std::end can be used as well. See the documentation (1, 2, 3, 4) for more information. Note that contiguous storage cannot be checked at compile time; if any of the parse functions are called with a noncompliant container, the behavior is undefined and will most likely yield segmentation violation. The preconditions are enforced by an assertion unless the library is compiled with preprocessor symbol NDEBUG.
    • As a general remark on assertions: The library uses assertions to preclude undefined behavior. A prominent example for this is the operator[] for const JSON objects. The behavior of this const version of the operator is undefined if the given key does not exist in the JSON object, because unlike the non-const version, it cannot add a null value at the given key. Assertions can be switched of by defining the preprocessor symbol NDEBUG. See the documentation of assert for more information.
    • In the course of cleaning up the parser/deserialization functions, the constructor basic_json(std::istream&, const parser_callback_t) has been deprecated and will be deleted with the next major release 3.0.0 to unify the interface of the library. Deserialization will be done by stream operators or by calling one of the parse functions. That is, calls like json j(i); for an input stream i need to be replaced by json j = json::parse(i);. Compilers will produce a deprecation warning if client code uses this function.
    • Minor improvements:
    • Improved the performance of the serialization by avoiding the re-creation of a locale object.
    • Fixed two MSVC warnings. Compiling the test suite with /Wall now only warns about non-inlined functions (C4710) and the deprecation of the constructor from input-stream (C4996).
    • Some project internals:
    • The project has qualified for the Core Infrastructure Initiative Best Practices Badge. While most requirements where already satisfied, some led to a more explicit documentation of quality-ensuring procedures. For instance, static analysis is now executed with every commit on the build server. Furthermore, the contribution guidelines document how to communicate security issues privately.
    • The test suite has been overworked and split into several files to allow for faster compilation and analysis. The execute the test suite, simply execute make check.
    • The continuous integration with Travis was extended with Clang versions 3.6.0 to 3.8.1 and now includes 18 different compiler/OS combinations.
    • An 11-day run of American fuzzy lop checked 962 million inputs on the parser and found no issue.

    v2.0.2

    Files

    • Release date: 2016-07-31
    • SHA-256: 8e97b7965b4594b00998d6704465412360e1a0ed927badb51ded8b82291a8f3d

    Summary

    This release combines a lot of small fixes and improvements. The release is backwards compatible.

    Changes

    • The parser has been overworked, and a lot of small issues have been fixed:
    • Improved parser performance by avoiding recursion and using move semantics for the return value.
    • Unescaped control characters \x10-\x1f are not accepted any more.
    • Fixed a bug in the parser when reading from an input stream.
    • Improved test case coverage for UTF-8 parsing: now, all valid Unicode code points are tested both escaped and unescaped.
    • The precision of output streams is now preserved by the parser.
    • Started to check the code correctness by proving termination of important loops. Furthermore, individual assertions have been replaced by a more systematic function which checks the class invariants. Note that assertions should be switched off in production by defining the preprocessor macro NDEBUG, see the documentation of assert.
    • A lot of code cleanup: removed unused headers, fixed some compiler warnings, and fixed a build error for Windows-based Clang builds.
    • Added some compile-time checks:
    • Unsupported compilers are rejected during compilation with an #error command.
    • Static assertion prohibits code with incompatible pointer types used in get_ptr().
    • Improved the documentation, and adjusted the documentation script to choose the correct version of sed.
    • Replaced a lot of "raw loops" by STL functions like std::all_of, std::for_each, or std::accumulate. This facilitates reasoning about termination of loops and sometimes allowed to simplify functions to a single return statement.
    • Implemented a value() function for JSON pointers (similar to at function).
    • The Homebrew formula (see Integration) is now tested for all Xcode builds (6.1 - 8.x) with Travis.
    • Avoided output to std::cout in the test cases.

    v2.0.1

    Files

    • Release date: 2016-06-28
    • SHA-256: ef550fcd7df572555bf068e9ec4e9d3b9e4cdd441cecb0dcea9ea7fd313f72dd

    Summary

    This release fixes a performance regression in the JSON serialization (function dump()). This fix is backwards compatible.

    Changes

    • The locale of the output stream (or the internal string stream if a JSON value is serialized to a string) is now adjusted once for the whole serialization instead of for each floating-point number.
    • The locale of an output stream is now correctly reset to the previous value by the JSON library.

    v2.0.0

    Files

    • Release date: 2016-06-24
    • SHA-256: ac9e1fb25c2ac9ca5fc501fcd2fe3281fe04f07018a1b48820e7b1b11491bb6c

    Summary

    This release adds several features such as JSON Pointers, JSON Patch, or support for 64 bit unsigned integers. Furthermore, several (subtle) bugs have been fixed.

    As noexcept and constexpr specifier have been added to several functions, the public API has effectively been changed in a (potential) non-backwards compatible manner. As we adhere to Semantic Versioning, this calls for a new major version, so say hello to 2️⃣.0️⃣.0️⃣.

    Changes

    • 🔟 A JSON value now uses uint64_t (default value for template parameter NumberUnsignedType) as data type for unsigned integer values. This type is used automatically when an unsigned number is parsed. Furthermore, constructors, conversion operators and an is_number_unsigned() test have been added.
    • 👉 JSON Pointer (RFC 6901) support: A JSON Pointer is a string (similar to an XPath expression) to address a value inside a structured JSON value. JSON Pointers can be used in at() and operator[] functions. Furthermore, JSON values can be “flattened” to key/value pairs using flatten() where each key is a JSON Pointer. The original value can be restored by “unflattening” the flattened value using unflatten().
    • 🏥 JSON Patch (RFC 6902) support. A JSON Patch is a JSON value that describes the required edit operations (add, change, remove, …) to transform a JSON value into another one. A JSON Patch can be created with function diff(const basic_json&) and applied with patch(const basic_json&). Note the created patches use a rather primitive algorithm so far and leave room for improvement.
    • 🇪🇺 The code is now locale-independent: Floating-point numbers are always serialized with a period (.) as decimal separator and ignores different settings from the locale.
    • 🍺 Homebrew support: Install the library with brew tap nlohmann/json && brew install nlohmann_json.
    • Added constructor to create a JSON value by parsing a std::istream (e.g., std::stringstream or std::ifstream).
    • Added noexcept specifier to basic_json(boolean_t), basic_json(const number_integer_t), basic_json(const int), basic_json(const number_float_t), iterator functions (begin(), end(), etc.)
    • When parsing numbers, the sign of 0.0 (vs. -0.0) is preserved.
    • Improved MSVC 2015, Android, and MinGW support. See README for more information.
    • Improved test coverage (added 2,225,386 tests).
    • Removed some misuses of std::move.
    • Fixed several compiler warnings.
    • Improved error messages from JSON parser.
    • Updated to re2c to version 0.16 to use a minimal DFAs for the lexer.
    • Updated test suite to use Catch version 1.5.6.
    • Made type getters (is_number, etc.) and const value access constexpr.
    • Functions push_back and operator+= now work with key/value pairs passed as initializer list, e.g. j_object += {"key", 1}.
    • Overworked CMakeLists.txt to make it easier to integrate the library into other projects.

    Notes

    • Parser error messages are still very vague and contain no information on the error location.
    • The implemented diff function is rather primitive and does not create minimal diffs.
    • The name of function iteration_wrapper may change in the future and the function will be deprecated in the next release.
    • Roundtripping (i.e., parsing a JSON value from a string, serializing it, and comparing the strings) of floating-point numbers is not 100% accurate. Note that RFC 8259 defines no format to internally represent numbers and states not requirement for roundtripping. Nevertheless, benchmarks like Native JSON Benchmark treat roundtripping deviations as conformance errors.

    v1.1.0

    Files

    • Release date: 2016-01-24
    • SHA-256: c0cf0e3017798ca6bb18e757ebc570d21a3bdac877845e2b9e9573d183ed2f05

    Summary

    This release fixes several small bugs and adds functionality in a backwards-compatible manner. Compared to the last version (1.0.0), the following changes have been made:

    Changes

    • Fixed: Floating-point numbers are now serialized and deserialized properly such that rountripping works in more cases. [#185, #186, #190, #191, #194]
    • Added: The code now contains assertions to detect undefined behavior during development. As the standard function assert is used, the assertions can be switched off by defining the preprocessor symbol NDEBUG during compilation. [#168]
    • Added: It is now possible to get a reference to the stored values via the newly added function get_ref(). [#128, #184]
    • Fixed: Access to object values via keys (operator[]) now works with all kind of string representations. [#171, #189]
    • Fixed: The code now compiles again with Microsoft Visual Studio 2015. [#144, #167, #188]
    • Fixed: All required headers are now included.
    • Fixed: Typos and other small issues. [#162, #166, #175, #177, #179, #180]

    Notes

    There are still known open issues (#178, #187) which will be fixed in version 2.0.0. However, these fixes will require a small API change and will not be entirely backwards-compatible.

    v1.0.0

    Files

    • Release date: 2015-12-28
    • SHA-256: 767dc2fab1819d7b9e19b6e456d61e38d21ef7182606ecf01516e3f5230446de

    Summary

    This is the first official release. Compared to the prerelease version 1.0.0-rc1, only a few minor improvements have been made:

    Changes

    • Changed: A UTF-8 byte order mark is silently ignored.
    • Changed: sprintf is no longer used.
    • Changed: iterator_wrapper also works for const objects; note: the name may change!
    • Changed: Error messages during deserialization have been improved.
    • Added: The parse function now also works with type std::istream&&.
    • Added: Function value(key, default_value) returns either a copy of an object's element at the specified key or a given default value if no element with the key exists.
    • Added: Public functions are tagged with the version they were introduced. This shall allow for better versioning in the future.
    • Added: All public functions and types are documented (see http://nlohmann.github.io/json/doxygen/) including executable examples.
    • Added: Allocation of all types (in particular arrays, strings, and objects) is now exception-safe.
    • Added: They descriptions of thrown exceptions have been overworked and are part of the tests suite and documentation.

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/home/sponsors/index.html b/home/sponsors/index.html new file mode 100644 index 000000000..2abe5d527 --- /dev/null +++ b/home/sponsors/index.html @@ -0,0 +1 @@ + Sponsors - JSON for Modern C++
    \ No newline at end of file diff --git a/images/callback_events.png b/images/callback_events.png new file mode 100644 index 0000000000000000000000000000000000000000..09aa2b38355a7227b444b5b6779f2c7ca9fa05d6 GIT binary patch literal 46039 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 UkR#h1#Q*>R07*qoM6N<$f`xGfOaK4? literal 0 HcmV?d00001 diff --git a/images/json.gif b/images/json.gif new file mode 100644 index 0000000000000000000000000000000000000000..8219866317ea21d2e5e07a4f7ab224a45b9b8bed GIT binary patch literal 1644689 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%0A_9$l8~<$mav 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 z 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

    }e)s-TIf{mvyUM)s24?D9r9995^Q(w_(;yd64zt zmUz;{t`;UxqfG3JLIELwbu&nA(_`;bN{;mhQTy7%bz6Yv8q`cpd;`a4=D2SsX}adV z!T4C%E0}h5zjPykeha5-qtmtVY-8(~c_!g6A=PxSjWFJD52q8dm|(hO>a-N%xxIR> z+X$GBOOE}nsa~~5u<9}i!fYq9SVvi#e-#{i`j0WQa~?NK1!2m}dE~tt8(bRit-dSY zl3m~aeC{)o@0+FBQNlwg)$-<;+DhU1Ru?)LZ8hs^I@_i?_59hLm%86_vK+I^tfKWl zZ3r>-YIfX~AF#Cci0~vdWf7X6bb)m`JRJ#7tc{9K6YbXTy%BP}5!xAZKI#ND=O$X$ z4D2KT{NmXCP~vN;&by!}zuHjmdX>G2EOfe#`syD2RQ2uloEWDUgrR@-%oha9_f9O0 z_ZRkUn+~11C0ByZ8D3=(W}C;qSo<_NPeX)u8b@dUi}7iR^Ycpf=gwJv=>Mf=V0R_! zeq7<6r>?q?WWwgZxxZqIwYqyhtPjA(!=!(NQ!Vum{?sJ(z)pE?0w#?TOT0&MqFixmafizc&sV03`Z(ORgnC^g3vt9=^*WOgi9be$untC9vL9H!JY;ayo$V2Jfzp zM>{!Rq?p2{b@SigzyF;-$kQ+aKn&S;+fpEsdL6=P!BUULn**oDU(g$tdz?9aywjy8 z#%m`2D43KI@K4o*yB4Qeh}SN>9bR^uUlnZLikBT2W8tNrnZ7ld1i4-A%0mtMaZ0ar z-A8%kASJDjdjMzKd~iMW_(sixW~*KJ%nuVAs>VM*^_$uBW_s%8o5m??IO$PPzo1_< z03!Ozkj3xhcjLFZoS;oEmy2lkj`VheJ?^&I!!W3OgM2K;lKijLFeBMk&FbTBzS(9B z?o#<~Z*NHT>_e54hgNK%dH?h+ZiaeM=k_*!1oA#=f3EAqv%Xr*p4q<{{hKlOC{5e1E~e!v**I(S_irkF+dq{uuwq5Y_)t_SMf@0S+;b zG_Vr)c`yG=>OX6Hx8$4}`>dPEns8b$IlJu<>*258Q`VEg=AQY8>HbaiONWHV*NsiV zzbf2u=|8hI(!x}p`S$x8E=}p0fWd)G*h z_Gi`4zay91y=#7cN%s2>36>oI^54NjQ?(>C5 zNi~8WZO3VtB%ai2%ubk{PX(N_#+}#I;nfE~ms){$s%a9xIy~<>5YEAQjYQ9S(Ho6| z1obgOqafzHggT|48OSG7UQsgv|1u7#WHs2wAH0Ok)PLLE(K|o2>PnxEUTC4{2(}

    GR$J*rb|s$-DyELRf5E4 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 z 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

    Rg#N7*TgO!$xN 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�+10R)1UBs%d!HVh)SgptipYG1xSdM!!g_j;Yr_t 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%0D*T_U5n?OTD?h7S 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%0AXpp8DJ8v-xJ^b(T z2v7VHFRA_%Yuht3La97Ro9L~`iu@?y{zIK@q!E0yj7+sq4EiIR<8x!%?X|#5Ou8At z+x)ycU;Ys!j#U`(l! zX4@v|7Rbvm4$R;f8v!-wce;BdLm?KBdK3f@glS+D7ZjXZWc1oV$jGsj8aYt-BAB%W zQ+|w==<$O+d&NBcN`Oaz9QRa$9!;KyrY^9PGN%#JxS_pwTCb^XJKhv zR(TQuG@t-LIUJ0^zHx?{MsU^KhjCa4iO4e8-$3duxE#$ZQe!ALc+CoIA1jALcTwCg zPqZv09x;Mm9i+gB6v0fyyl`OBmt@KVt{NPl8UdeH@RW76U5LzfWm#-yE8&HCeMDK~ zp_X_qAJK@#%!o)TQ1sgT-Fyll z83NPX){}!pz*Xb=7UGUDFUj)agngh}rJ>+sFapoDNdfb8h2L)pr?2y6Cef9%4ac+u z_AE%5K;oDJ5-WH2GO-nzlxo5NQlfE~8P7Ns2$}Cd@9`654vhjY=i{ z)&lHRD_i>xy<97sY8iCVLdY)7YR4Xs2k%%om}}=c(5cLhJ8C^Iq`MdAaQq zTN3*y637w4#g-Ynt=U#wS$_FaE(PXEa&Jhd;-VL!erdk)u&5E09CDSwot}h)0BPFZ zGzo9$d77-RrRlzZ7R@ulF$hLEq9v~!&Agrq!KArh0hCY1&Eae~YrX|6?Pw~iC4z^{ z4Z04&NX?-YcS7)%+rNNN z;a*@tJa051yF=v{?H`eBC5PR`C+Id6{of?%sPro;sFCk zIos83pfZcR-%d-IZIQgLgghE(@v$5dHZ}Ul{=g%5w{N$BJvB*Nrlv! zym}~KmbAoxdjNmr4t>!j4~l@kiQoZEmXYQaB+4WD^WR9Tq{YZn4ZRS5{t~KME>G@Q z6pV=exEOF9^G5YIK6g|6#!nRKvkJhdyjDQC=|1!k3;&z8%CRK|`Es^HW|&oLIr+1) zBbCYmuZnzDSY3MLZBQQBdMMcxd2b|FjXU&GPC&;wPsRJipI>RCm?E0v$`P*OkOsct zfHzf^Y2c}hToxG3ViW}|(RZnmJh1i&tH2Lkn6U<#e7`MJHVhEz+2h| z7H2{J^n*gb*L{3los$fGp-{#!MR7M3#aEflOz1a>mZXDsN7RIz4sZ^1Iswbmh)ktCfKlFLjK(-5*y0#{G zy~&}S6X#p(Gy;8w2fqL$d&=4LTcJV~atwK1(bL6b;w`>J0f~s0ohv%+^X1U+$B*jU z-|Z>DvNJ5jjAQ98ppReXn7U?bl`^<|dKhWyPkH=SQ^CULQ#*A+<*oFBd=tPxfr`DI zjZyD?{B;3R_L7kOX}r!aF1r43?6ws`re9q5>Uu1Dj4THR{mLc zP9*SrqvOVvip5QVnm|IGdT)WtdlK;uW(kjcL@9|~-6-Z+(tJ9P5cF61TbjBWJ+>Yb zwsuw;pr4YyqQV=>_0p~aN(dCM`9!bOCcUCSCCnzkPt`jLYf&uiBm;#)wO|0gD&wrb%Yd%)CW589VxL zfYk2YNN?0QJf2YLsqjdpOj%++g6*DVXq% zhZR=Q!4`61K`SIJn>TzNH(XF#e6*I^W(DUhPn!SrPMp4<95fz`?I{rJ3U(VQcaV43 z@g7wGsy~i0ulK&Sns}o-HmE&uU8Q~6sxMe|;+~MDj7q(JsJcY65er3%wIUVB&v~7O z^I|Vvh@pez+0gJZ^d4I|i-5qBhfw7X^z(;p8;>U#gKLQ~T>l=^&vwMo=fw%K`B~0P z3WJ8_O#u%@s`Sc9T8Lnwez9?3g-BahdWHysIPRR^)4CeX^~>#D!9%EJ2j4Bvfm-|c z>(;XmbwA803~^8d@cx0kI09?tl3qjCgAAa}mHkq6V+KD1uMf7-igz^#nJPz(U!U@j zS{Na_-A7y3aYE4-@~P`0W~{|y*4MN7+I|<<8YbgzLmmp2n*^jH-UDKz;Jg7!bB1m! zQSzfvXPN|cA?OlYb(}_R_}9S^yD>_Y+Qe^e4OVThQyQEC4 z?!AP>5*P!fG6JZ*IK^lYR@2dR?vtZL9v;(w3!yPJRCLg)O6DL#18109$U|A>U! zHHfNbcTkD1iFW^S$jNXhP1`TzIGyk0wiLop@}7|RHvnTh`yUoJ6F@LpQw^v5%8b)K(&-J8rP|6(O;Ayfi$SP#)$93hyr5TBE>8yN-T~%Fh)N2sK%g^;4Y{4b z_oy(jh)1WMAf!KVxh>h?sy8x{rGFW(AIgmLEciSkq5 z$bxx4#AY3s%HpZq!%faljm+>`6l?#MIFmJ2k)@y4_xA& zO;kJ#4y|WK;dM?UcfbMR$y{M?!WF%TQ6(MTqoRWy{QC7PIvDS)2R(;Tw5-XjmrZzh27wZSrdc685M)HqI!+~S8G`LNom6;+P% z2(GI|;kT3ECg9Li=p#+%W=7h?LeEET2#rj?WO8>}R8Z>Ln;`qrm|Ozf*m3AG=*B>N z*;9|P-FH>zcPO>*EEMc$1gBV|mGtrh2*3QR$5)edPqAVEbrZm_ZK zsOg$d{}+i{@&uwX@Zo_mhLB06s+mYbcqPJOapUH?O6kV2k>fKvRkOn6_=LV#C?zuJ zr3`0ctx15C<+?InD^Y46+J;5%YUPth! z{B$=3@R3bJm_NVSKdmeCMlPwLhxc2v2aUM10X5*|zw#Y%0Wow&?^aQ*lVZ$$+pvLZ1^ zW3W`UfwI6Xnr}w zOn9x|osf??buD27Ns~#BLH*?xv?S(HwTbTr8SD^`mmJ)48LSDSSxsbH5 z-~72~h159FI{osneXK}Zrn{NpEghJl?lUp+zSFizVt5?y^^p6JCl4T*+KZWHN_x;I z0%kQ9STdFtH`%-B*J6*9yHiO?ok!WQzY!YaTVo`8ege*M{;S0fxtVYT3m)=&@xwJ~ zk~ms?D5DSUa820IEf#yL3M&gPuw0$0(I3Y0ea8;Vw4=h&db2hA^}K-NODFfDFEz*ZKRQhi7 z!>lr_>^~a|b=O>04@EpMU|6G5&lsPQ(()T$Q!)-hP5t!u`%X`hGIM?8@K3kFd-Utf z44-d9E8h31Fd$F0n<$HxGA6O+gZxlaGFiD7sp6CS*xaj46Tze8y zSvS9u@jW&cG3)HH(gj%p4dGOtp(#hDnP<5k{10P;dnq&|!4wIGLs7X&iQzwg6v8ZJ zNpdw`|2==X;WQho_cn@=fI{|qLP{Sqc(dpeZu8xK7NkiIJbMvfzr=y#tN`JiW;T<4gO6E2US@L z09!o^cY@QyMWw|be5o!5{l0Sbj%9v(i7ankX2vXq6biLc8whQ<^l~(6dm65LH(#F*rCx3jf?=@I{PPJr`JF8!N(0s#>aA zJc-SizD>jqVKa1xuy}c|C3&CvJdF-C+j6&;Ky$U2_6yu#>ZI1qX)PT^9o#R)=O#tPfZ9a$D9uz-Q6N-VOl&qcG*l>5 z6+VP@)Jhr~(sCCSbJZ40B^6Smx_dTK%cfWCrCXY$nY?| zUdoTUc-K8DUNih?X?pVol^9iC&2|-zAkwHkmYa&g^RcJA95a2^Z^eJ*>)T_0i4+!6 zkWSY~2KaU#0s;x*9=L0ysfvMI8a`AcnO6@!-3@BHnlgIOoJY9m%PxFwC!+YB>pK)i6IVh2`*v7;m@tQcVi%%Qm8GO zhHp4L{dT8>!$=u?(yJb)YBZUlT7s{Ym;Xt^+J}~nrc_%s_%nvBqyaM$Ca8@tn&^pZ zv_=;(c+E2meJ7fx3tNVR+z2yfDKf?%8SOZ#=yVu)u{O{Y8PHXYB6t$n2)(TWirAyH z>Gdd=u@?XJmdX~=R_@#7XasRM?#E*YD0Q0ODt0e0>bKila)Jmuw2_$0j7DE5rCY?i z*-I52sij<9cyH>>NM$AV-VmfN*^hxJk)iHnMPlQ*c^3>km1Hhti>F)EXL%z zG!r}IZWjqN8R{C`Fd1rI=5SBLQ{FxdA1fqJgP+A4-S>33AGd1$v=i{!#JhKzdoqAL zZ%v16!jPq79Y*Ncz3gx=k(zDJl4s(cdr?||9Oq1wK${8i?J9`vCcs9hX45t$fzFhA zEwt(a*tfDG<4|@e7gF0a8!a3KkuA2pwF??x?j6PPp;M~j9ST#lI)J}1kgUzcs#x>zqX$KAC4CT>qOb?HJdm%m(z;HOE=BWnQjh{q`NDpxpC0mvw^1%1 zmx>npyxeiWuzgzj-5De#Mo#86>}2<8OGH*7i{EFeVjtqWmhuHZxjW5K8+|DCpR*8_ zBue4kJs+~gK*~MaqJ$vT!t!;o%bj6(IfxYvv>)4L<@|AZz{z}w9n$Y9-*+-UbHz!W zRNK`_G`TQB+VsE+YRvXr9S)$=Vod4X)_mT6DO@GFz#JavzCsAcNDS-zl9~CtjLnric z@}8q;gDNUeh%^Z=zQOv_Uwx%m8Y@~}Jkhfa2exu%wCHpu=Hwn4nX!?vAKd1MvvbZ`1NVQSCOn+gSpR83LXNfx7eiBMf8l)1gCdLOsZAu> zv67T_Rr%xCh7jQ&H8em;2VG#K7n%r$0}b40QVW0`x`-daR8pczyD)qqQPSHbfHuHx zp`WQtLY}&aDz;B{4PCv>LXNH%s4B0R1UajtlVd6MCoy0sJIDxN$HyXXmGY0L%rw|y zk2Y#t!T-jwoMOxB!uVoZ6g^=?7fQ-1G=I_mXo(yDd*h3)up~VM3!l8l5C*vy-eexK znISM=?rKP91QLaka&C{;7e(2;1Lzm9UYpOZbZzFGZ0IDb*yqU%)=J=Zu!YU7WlKb{!F4_-uYcdLuAg9M zASU=W6%Pc<3xWeA#8+E(eoQX*BHBxRSY=mSZqU@G5aeG6Kr^%*%M=krpZhJqJ%s*P|wLl|;p8pF9L z*;PydFTMV1sH{I00IQLoGLvgGADM?idlGMM&nu8es_8xYWRWE z;{tVJ&1lpNxt7rC{Um8rJA2rs;1(Xf=KeKmk;BtV3L?_Nzb*p#KwjeJbP(UP?|(&q z)@V+Z)u=st^qd#+_RYQIf9CbS!1ri(u#<~4%u08mbJxW1lLJ7FhI#zPvPs{QZ_bAq z`OC&#bE>n8M7pDY(x~5a-DlE=FEyT?44~7(k2olIdBjNAyFiMLU9ywAoNJ_uu}2f~ zdsQSexBxV5^No|at@2Ul+FGYmVSMi2J!AMGHPo!F>dB1A`el~N<2Xv+Y>&_*ux-c@ zHuaeGJ-?6PDxHxx&!O(g#7HsvicS^cQo=SD%K-vh@Y_^rk!7K&dFinS3r z^`hT?zLFBfi;b$HeJiDoyi`@#V|=xnrSFLT!a#rZb@Jan)M8ctaSe51B6Bif0%l8H z3=;!3gjw}~{%P|;i)++E@6l{0c8`0#Ek*GV@)F!7Hrzw|p$o`P#!u_>F{caV9f}hS zVYzJi1b_5gkds>M+LdI~u*3zR!VaOJa}x=iyUPnXGdM2C`{7ehW7senoOqWv2ZG<8 zhHC%D+Med0xW=75k$Yb@E&+L1O?o%}7-RJGbHj7bw@$@EXRNUYSlJf=gG0o48x`^` z2w@9|jK|{+f1iT=&CH)=%b&zkoD&|QR3BXhBK^SKH%lGKiFEo@_L>o1FHt_2?2pdf_8bGGISn~2$xvvViWzt~!*{1?H*s!|-@W;yRL zO4$gr@*aJL!@K#M8;gZx;(t)Po>l-4o!9dc#S@3eOiA{Psv@syZ(Aw+ych#EbCN)p~%Af8n zHTxVM{8czRS|5Dz{%iL<>FIl4*Oais-~pNR<<-mV8Lgd_&l$h&F}iIs+@}ol z>wZ??y2apfxz7aGLMaZd>SRNv=8PUXO0SV6Bav&CHt5+LM`CcdS#Vo`1vE0k*v}SA zeL8Eal6?+N)fSr|UsEpq%xvs2a=g9jN&j|x?o~FM93#0OOX0>7gL?l*Dx=nu8S!`C zHuDfutY4n*9YbgpP$^bh^GDZEjNK_Bq8SZb1y7aTDdKE7$5tPstTW%EV-($*z<2>YUp8S&*OVvzzGS-57baJ}My<3_*XguORlAyo;r#ugQ zokSfHv1T#(cCqd4e)fR8pi%v&o&b@yo$_{(_WiaCkΞj7`SLz%TU<)OhzSCH207 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ⅅ^d!9L~hS!p|-5%?lP6>yxT(V^}sdVOU30 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%0Dj#x{)DhFAR_mTT!m!j=<(k{qR~NdK)Yp`T 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�AIPm|ZnV&CWx@p^ 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

    {wK~p{mUAeq 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

    (~2x)2Q1L$}JD#7JT@~KzXv4 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

    2f%mLRT(AaxX~mn-~tgGW(oyYw^KMlr<+ z3T7}t&fG6nqD6WWt0t`TBJL9=BiMRrN+YANO#(4pA zb{Ya0kZ8mdA_@&afC3(Hg$Vyl)0}3amIV^$LMLSa2Vj8U2s4T&pc+aGctRG;8q62c zh5?fnfB_W1U%9vf&3*oJo<~E7C#ZMQ?tiO9I1YuRGrIo;SVgZSQ;Id;i`myzlMco$r4GJm3N! zIKc~U@R!lj!u`h7!5i-IheJH#5}!E5=VC%?%go;u-#EuR?(vUg&-}zi<_3N2$MBzLiI?;=6^rIvF-Wxga>u8?z zr$asJQlC22TRPVG%~0c2-#XX3?)9&O-Q!vhJK4)__Oqis?eHDD+S~5-x5GW|a-SXB z=Wh4A<2~7`#i>s#;o*TX*cvj3kw?Q3uQ+v7g>y5BwTd++<- z13&n}A3pJmZ~WsUKl#dEKJ%OJ{O3bI`qH01^{a3F>tjFr+TT9+yYKz)gFpP@A3yoa zZ~pV6KmF=oKl|J7{`bQ_{_>wc{p)Z4`{O_V`rkkQ`|tn%17H9O-~iGNCDg$I)`29b zgaIO;0utZ@LSO_kUkZpo1y-OccmxGnpa@`~1bW~Hf}rk6!Ul?f3wXo`ZlDQz*(J1r z8dQP|v7ifv;0)4W4a$WSkRTj*1P*SX4$2n{Y@iCL9?Srt1qz`JB4H9Dp)8QV29AI% zU<4C7ArxAMAt2xtUf~O-3<_>w8(4@HVj&i4q5ooVp#^%O5~5)mMxY#!U=4T#8*ZQ* zQiukU;0B(6%A`RZN`ZyYVI5ZB9WF*5lHeX1g(_fS2gZsaULhi?VIw*s-n{?`9)d?i z;s#FQ9Qxq~mVnBkUCT3y7#;s&nbBf?@Vx?L)eAPRT{ zEpDJKR!ATE;V7bvDwKdGQXwdYqAw-}Fbd;Qw4w#RVyrA<1vaBBO5-$s-5QV}8hC^? zZXh=9VknB@%BX@I%m59%0V7%lFV>+k9-}ytqd8*4Gm1boz6w0bBQ@INJwBZZkl+|j zgg$N{KUPKzu)shPWH4HwIzpB}668P{Ex?rYO#) zQLrXL0tPAorw9nAK$Ky0S|AJzrxl<8Zpy($SON)BLM0So5K=-E!e%cnXF*h_b&3FX zPQ-cEAqzO*L44;1hUa)1VR>EzZ)T!za^`<3Mga(@fFc!umdG5C;0$;Kf^MLK8ipjC zW)M!oYLcZ<7(#N^;(Qi_D%_?wwg7Dk1czGZhZ+QQ0_Sw9XM`HzgigeT0w)S+=tMMU zSw<&{uIGpz1cU-747g)0RHqzZ=x44$iw3C$!l-((CkeJdj&`UY)}e?4Xp(N=k`~0DMrTJNsU`wvjQZ%C0%x2O z#Eo95K~%z-MyCo+>OoejLENcz=4qFzDqbuI+N>&wr~;_=Oe3ndrpC% z4yy_n1hj_gre>?Qnrf1sqOdZmxSA`Y*5j+ntDte|ynaXLMlu`8=PtdQbEK{Y{gz|#)`nk5=6Hu zDn0d8ZmU3?tOb&Q8-#)^R00oL;0T!G zjj})$q=5|hVI2^J%W@>lKI|BxLe6I5&ej6IYGMsg0Sw4$1&%;wBCXOgZ5=x8Ku9b{ zQmn;dED4INy}HaI6kGMRD%^TVlPYU1;H_bRtPJ>sE5ty)Vg$_|1kqOD*$%{)%46Uj zq@YNl1xl(wFs>*%E~bh=TA;G_?cYvr1^Vki7_JB)u0Sa6;PxtFXl`&SqeQ9% z$m-`n2%;GlYySnN!KQw#2&e%;jBe@H!s)iC>w3iJiogu`geCA|cfRWe-tIt1LhkPF zKzwcqR4zx_Ez2N^0f^i6)$R3a$VNi0Mq=b)d@Tw%F1cduw5IMs)IbWjZwfdlK~%yu z76g8dW11mPM60q5;NoFqnk zEe#liEO@3IIxh*jD?!X|1#)mLwD0@I?_E0ZK~(TXcqR(aCOmRu2M3`+gs=#Vu>Y3m z{_?N)rp&Z}RQS~^4_`>yTA&+v1QA!D5f_Fkkl?o(gyD_=>W-vdd@Ugk1Wa0>6cp-2 zU~vU%G5=mj@I^5320C#;K=E8uu@uj0VuZ1U3a=QGpb{5^3#4G}#xM#ea8sml@VcT( zjIjllF+o^vs#fP63&i~9u|RaO2z;>+$IRILT=oUABU6ZIZm~dEvSA=H?H)ufc(Ny} zacj~ADpW!#m+~MM1Ob0045Wb^Py&diavhEUE4wl*dqf)_#3onZx(>uAgYs0G@+ohi z6|?X9M({qiZXbJuF2|!RII}B2vnzDy2eT_%X0QhXb1vchdHE@nKQnyOS;2J@g zRLoGx5UyPJIyPj~>J*Fd*E(llL^WPewLl!gROnkI zQL74-%x%kIwsbd!8@R1UfcFNzZDAz0U5s{37p)7_Kzp}$N}IF{SgrCNgdE5>aMJfh z@b)32wNa=y*s`~KvnC^l@@K=fY@_0F%P$GKzzjI}gG0E3=QlYk^HKcwX9l=?!*@Xd zHgfm3KoE8X26u(eg?-Prcc+Sj4L|`nfKFXEWiQ>)bvKGD2JCu-jYD-Di}qU&1cO5E zLkq+nW5i*~0UCfTx*FzD8hIV2uR-j0EikhjABB%sAPWF_EeLrrbGBkUIsb<%I38Qz zB{s!KHwBen?v-b`my`HeZ=jS9L<=l8g~#+=5c!fTDUG+xi^EK1%lJ{_xp~htn-?}> zgo5CjG=xVlullS?jP7)%xk?~{<&uD0MEV9!`Yj`PK@@tw);FT_Zl(wMFo*J`lOm}1 zHnDodrd!~Ix9OKZv8g{g1-p7J{4wYr#0k{#@-{bLRQjU-xytDI%dC@StK5wLI$>0S zDSAY*ccEg8Z@O-|K`gSR)~^#DgsOWn{suEF*DzX=vMF;r2?}s5|06~`yPevq{a*Wq z7sRwPMwhd;va3W2GXoY-w{05FZyAy=R>oc)~v8m5?mD@5w^da>=Y6+0Q(*LYsGeyo@;LeM> zpcB1Hgm?u`IPqq@y&r|iAH>UBpu$Uhsx*AdJp9r5`PlabJf^Bau>E2%dmJ7@B_P6p zi$KN~#39IX3$xBR)YWzNM#f-`4=h^1Xlu za@<>B4a|Mr*P&DcehLbHL0^R4bM@s5cwf8$=oW0Sdef8@F z)I+~Pct5HqhQ0$Q2?XkJT5Sam1RVsd6iC5oV)SXMfD5oda;~=g)4%-}MEa*AL6E;U z0tAUvwFuUtBLZQ<5>gnZNcd1nL5T%jm3VmZ;Y5uaITEyp5#+-X9a)5YC}(1*5g1dj zAi+|jq>FPpZajE#VMCA+Nt#TEQlhGlJ`=`>IkVM0sW672^dlqflsSX0PZM#TqT(Jw>wjCuGZ~tDsd*#**fPimc!Gj4GHhdUy z;3LR2s+ zIzyu>M>8vklEy+(VK#(pBdChg+SsU5(LSAMH_Cb|NK&F8)u>XRFokHUR87)tIT23P zDAeaRk~O3epeqikt6DYb)r2<16*y2$HN>}IugaCOQ3;)v+G?%67F$AHX@J`X9@Hoc zZyjjBuK*V4R@|wcAfQ~g76_E8QO50d&RVn>pso)m(jtL&-AbTKiLOAmTy(j8ASqDD z^>+X#^rgxP2PAf&%vu&Xpe{Bwa>C!X8vig*t_LLM7Rf{ks0&Gn5+Tsv1K_12eRSx+AH#K04dH^_HllhbT#^?}Yvy%#fu( za$)eQB*_$`5hju(@QYqhCGulyk;CwiSYVbT%!%53qf&{wm7u~+LcAl$Lz=vDsunlN zaj``AiS&s~59!x}>d5>e7!rTnS*uhBiFH_$x*eq438EzOL#b=lx~x3+3G}_KzaIPS zwZDE8zZB4@ypGGQ2^5UQZ;Nh@qW|!#Opg81$Q1_8cMETg+=f;cq57M z%M%Eag>q>@BX&FA0Md6BE%-%jwYWmL-c}3u&5wXoVOszUP>_Y0t!q^IV8^WFil9~H z0r+D;+B%ZLy3EOiMXMJ zVnvg4tRq40m`6}fr4p`$f97;|LV^*%ky&1r&aP z8YtrFmJmL$ph`STAqH3r0hWtJqlnx5B)SpvwS@o#fui_;Sd+5hFA*lJ%a0y|#Q7PZ zq#MbhTLLA-^Bq7UBkkBh$Kr~Q;*VxlajE}iD3NxGPXH-X**@`?!KD23rcB4lA_gzaQ_vnVHN9G$y!#ko)xWW6=yo#vQDEGv@IMN1ylK{RB-vlLv(eE zL_nd}`3+!-0L7m`H3HFs3IKo-QK?%PP>X(*D`l?m>-ic;mPPmlVNh*Ly<9OhxCWr8 z8*!=r3_Cx!CS|5WWNTYkS`)$IF9B2`XkD~$QT!dPwC5v$RJY;^s?M*78+q;g>{<(( z@-wItam5Dl=g*1g^n9_^NNVwiQ?*|ADk!+fKx(4hhj16W;T7+A$y;9Yo)^7(TWtVN zOOT_Uk0Y8DfCHkCpoW5!xA&|I6y6&EiFnp84XCdJe(O|;3>T>zVQ9JL8wDw~s{r|} z#bVpCfO=B!!2ji903lp43PKEbo@YsDU1sJl1F@_w3xL8E9`M`7CgrhiaYaKF@C5z% zE3_J+XuAN!;)ag2wd!lv0iJM$C&aiePMFGZ1CRv(2Ot4X;O~6{Fo0UjwJryc@&hK@ zQLc=ztwnYMlG{oZCbwk(4tPQXHVQQz`zuZkc=BI3Lgu#6m&JY^Kuif@TelG43IbZh z+Wb-gja=3*1GoZQ2F=`%rgyxDkX%wE{g4+x8q=B9^rku8X-|`Pz3sJ_7D%my*IuF2 zrQXPFQw*~Bl`FX$A;bV1YT-n54aEU)K-vuG7s9G6)hBgJ7E-MR=jJ*93;-D@sH)_o zcu&{?F#p=E^_ANINOab2akE<1JEfIgp%7hTqPdD%2*2{VAkhwhP5)=ajjnqtR5bvL zw)N)|;-_6osrk)Qkn@@U z9Oyw8`p}79^s$5*wSI{>K_u%JjN32KHQ8}nY1@&H##&|fb?#dWG!;L$<;BW{ssJQ> z^12vUBDvn-UCo7;P}jxFwP4w{C!$dZCMDONW%;4YCEa(Hs{kb|XqsvS%XQ)MuucBHv3xM$C4y?nIdb?AOB`cG>~&qjJ`r+Nmbnq$NIS_6C11zX zrvVT^1rhy1j)1MWM%VrBdEa~A{~q|kzZTMKLfxg;g1QjrNYmk7w~l?@i0q0x@)eqt zcA`7oh3?3RlbjSPSGXe$Z9PY>ka@XKxcW8080XnuX4kfB_T(R5O^}^fjnf(5eqq1B z_}!7w`z7%t!rI&d`YfhgwvH?Mh3+&W+uXvsfE4}Jh>&J3+?2CDxyg1Mk?q_ED2 z6u`L_E&%qAA{HP3g%1T&Pz6_z1zXSsgOB(+!uY0wxu$R2Bru=+Mbr)r0VU2a9{-Rd z+DXDD?gS-*x*je3+GV#mg8RTPG5o~}jM9XKI4U089Na zYk%5h?Ka~3cCaAG>J)+#C${bCurq5=D41A35UxSS$Z(F$?`d z5dV=Oi*XYFZlwa_>%1%!r>`UCtPQJzx;|1P=FG01%*wQ4sK8MrSCS=L(j{M#_r!6! z(y=Bs>iF8JvMSLnR=d&XTeq$^{n*0_2R6BVNlOB~mJDVj*?yF`OPR z%-~WZat-@n(l7rKFauLC2QzP?QVk1&9EH*?z;Yu%t^jp10G!b)zW;6ufihoeLMLGn ze&){}%cU>x?J)3ZEbgu&z)UjVY$-cJuU2uWy0R9=Z6G&-$#Ae{%0%*aif03_a=T2c?rkJJdrz6hs44CiT-i zY69fovmm~XDK`Q#lk+O>vLmkVi7b@Sc zFI<#G31LqeKvHRxo&4fKjp*bg@glR6NeRL;tKz-@NFwL+KZ%nDt<)?)0aBsh0UBUZ zNslA$i%08>G_iuZw36wV^x;MXD>Tk!+7wuWRal3WSkdZD5i?FT0?bql3YyhfpVe8V zR3oC&zYZh{?95-LFFZM-KdWM-&Q!0G^S1`z3GNgv%Ks%8$xi{kuUv!_CyO*we-YuT zV)5{AGf_1U*@q(}@=WQoQzwGC$j@K~HaE+UT?33G&~+~T;!s!5d!Q9!qqQhEB2mr7 zQOU9`6u?o7m18^BV?P#T2jf_2C|M^0**>c+0yHWKlocndW3)9WJ7TCB*0?CNGad2~ z#peOcwJe|%W*$yw{j^cxwJwg-D-o6|qOvR3D?cYrPwJs7iiOlld#3xI8 z1YfCQqwtU;1`lPcj8^>x0l=0ZPPQ!$fJ;NxZQmAd<5q5yVq~eWL^}doQI=)-N-eA6 zh)@=0FS8?u7G~P>D7$t^gO)F*(JItdal@8yYyZMXeY5+h0{yyDC!;YQ85U~KE==c@ zYWHd*II2rOYip5|akGNCc+zCYRx}|`vsP+WMGwN}AQH7o8*FDGJt;R+NHtohdBd~lU_2bh2h*nn5k zcS{xygSRgB)?ZVsDq>dvI;6HhVHDOYaAm9}n71blcOvLYbBojo4mRL=G|Q?&Z2=?; z3c-R$;mN!=avPH2g3waQcT-W*0j)yaD*tPJKNo^SH?H7Ud^$>O%_Ry}xP@KnbW7C| zw*r4rl7Xw%EPsngr($U6_khQX5H2-~yI5|wSgz#6i@D8%XYy{#ma&{bjn|ls+n9~L ztbJ?Z@C?91gt#p-xGnN)qg)i^ptn$)I4fL%(Aq@|@j_Znv|I=P3a03VrxIm|_Fp=W zOo#J^a}bcJqFeLPbEgz^-M4EUED9hNl)L0C$u*{sY>BTdb+KYKwL;w#z>QIchaO{_$%TV0-cVx(svUD z7kKT-%sTmSSFT24w_mgOgr`EU_WzC};s%BvIW37-rjQnrCvsX>IVongbKN3Gqf$Zv z7ICv;qhv0dJ;rLKn4h7!DqgE?y#f^8O8|Iw6b^5*lv%8(E0C|Cj)4zBDjIGtI+?>u zqcQEGdG;(MnqqqqZ6SI>)hX%D_zJZ-ETp-eEfL+&503*NzsT&CsVkMEw}HPx1l!_v zx#EzG*-2GX@*LSMaufZacQ&iy>$)-&t>SCzxh?LQn>*rtzoK66uqIQ}j_qP$S^6s4 z>6Rx`)OstZb4FEK zS!)$6Tv{V+5;Lv2Qn7g>a{p~nhxFfw+MBVuU<`R;(HE?{I-QUDouN$rD!D4*StAsd zD)cJ2dN^UKdU^NxD!@!D=?bn9v@T|q8tX!U4KHfdf~s8kQ@hv|Jb@F2d$>J;oG=!c zse&wN*3%#}x7pOWHEp@gA`uF~x(flMy#q4GS}fq{btfWG4`8DKn;-yA<-;(I?Edh1n5H3H;ZleuhL zHt$6~>1JCOD2py3u0lt2S6fW=#!#f`g) zkb8Q$Zj*N}`9hrOuK(M*$2(hGLB|V$$MfdKtHQ^1JjnNkxvxjmNxc?Oovc1x$tnC=ME$uBTL~9gYQ;9K z$$KNLT!9NBDnqy{5L@vWdm`pE&fNn0AQKy@mAB43Ec}pB7n5!!d?J|4UCUg++4)A7 zb1F8RJ5xiIJIKE0vs*s703Bb!v`1)F8$Io zor>%%vL|B1Q`Yw)uPw%JDqQ{4P5r76UiS2o;l--pIsGi+X3@n1;_V$R1fIyL3e?rw z*9p6{wOuRlx$&y5Cgu#x71J%+mdS+O%=g?YsH>#Cg3aH&EwobIvR%$)7_|TS&d{B- zCj#U+ULuC7J5_tJW!+ixd%rQIT@&vLw}_2wnQ#Pb6E#=NUD^ld%C-~XM8Xq_uS zAqo^g0iuA)Ic*fuUICy0drN(@$7$jp9`5DdD(*h4&|dA?{^Fh9THgNe+ny^{{VG%r zKMh}*6aV<<<+t6*XPE`x=#3rNeKgr0+7{iMTR9)U|4b~H%)xQqzd52_*ZaYXI(Z+z z*UNn(s4GAvqNiPR;_5OK5s>MncFXlS&`&<{yZzl!*YeeUvaQi(6DBN2r3i^>Yzae3kec(Xz)SAfek1Y zx=3&o#RMD^Q4Fw%qd){B5tu~j(4xsJ6bG1`=p+Swy^0-6wyfE+Xw!~ea-nToM{48BC0K|e zfw_3|>fMW$=D{p{1AFyr5U}9Gf(ZvOjJUDmn*|)|d`vlSU59tYD$ZQFv**vC#cn;Q z;AYf=S8k5}3;7^}Q5+jeu1XOiM*}0Hn0!J}%S~4!3B9B!;N}3#KSw#BYEl96iw`KK zCQC8lO^OFhE*Kd$Vn&BpO|A|w^y2ZBCPk(+8O1L1iwP(i<*3-^P1y%0-|XoytzDDf zIb>Tzyio*-S6YnZTUNkHcN1;~EpT8&P%w6pV$%^6MTQrthgxVLhA5&}Nw{^v2LEHV z;)o!e#6ngqkO(4(Cx{t*^7!S57gAIuoOFs6S$+b!a^#R% zjk05wYntQ=lUbD1nVwPtW#flqv2;*)KP`f#lXX^VsiotUW>SIz?&PRJ0|Y9N6CZK3 zNK%51^rJ%2pp5oPi0fd2~#J1j>J z7^={+0dN*k6bmX8pH#;#1O-LkDs=E-%~AB`Kv8kH(01ltYVpO0mFSicSvg`v1}0vh z!4jr$WJ<`MwBiNGZefr_D}3DvDzF5R`s_&A%{1_{3p~tG7Dy4Nz_tVhT~RGi2=Ecn zrYX%RM-(H(bVT8fq_09A-h8vB{~GO(0>WKnuR)0@H&Oyq4+QkH1@Cm^+Ib4 zo%YxPl)dOdXya8iMOV`mx7KrGe3Q+C2axkzG6%qbD^EDhciIC*;dOptZ`ybO2KXj< z09|#IIOSejl=RX&HO}i;sj=Z4Xo2gQ z6uUv06SN4w*G5#|PI&8Q5`PCt%iaP&D}{jKb9mxN_`nhoSHvfO0$JF-77`r-tm!fi z!Cpl0^E8M#q<#_^i9${@yoCslX17bB3OS;&wr~t6rf6Zv+LD1VT!a%LgTxVL*cJ^4 zVlV95$pE#sxQOg5ZuC;fB98bhCj_c-4j7_A1mL!daPT03BMAKX29&=!B#QzOUg83f zF#BEZdBM}jyNFZ8M6B^y2MC-P6IaH8EOBs7j0oHc@y3HtasMt}#NtITIL3q2@hppo zf+82m$VMuXa$=Dp9P`q+21JdGraB`X13(I!2La_kw0DpL_^cLL z;Fom>lDvu5f)M=jpF!uO&sxs%rLhcz7iKzB447yGH2=-17fMEuR%n2SGh{+UaA+bU z0JSX`;3*(Csi;DJb0E;v8uU7HPo71jaebtSH911UgWxD4-QrzxMz_sEW^f?~9HTAY zhMmD>@qS}0K#>S()sw45=K;WjyFUm!fBq^&|y(JfS7Sg0fw6p4sJAI)bl zii|cZ;`3B$p+E>NAkHA|N#OZ3QY}>i^jQzMg8vqv0L6LkB)!;qLUTE)UizSmf45ag zZq>ry01SY2a)yi=vn;4YH9#C>-m%kmf1a{rsSsX(n=-Rx+j%nAh(PFf)8Y%e=65@M|h zU=#y=^FZR9I0L|Pf4bZBKn9$aE5^;bc1G=B5nJbx2)7o!9$a?_vf{zSkX z2Y}>yiZgO+mfF=K8FcmJcwjjKasR1PJWdXAG*B+7agKz$yX zcjEG4Zqd-9i<_t(W9L~bX# zxdR+45&UAhLY9g2TBLQsWa(<@O%JbFIZPqpCNZxCN(S|912j?m#dQC66X%zH>!%O{ z$bZVi7y1Vj3%D1Y=Shh1eg9CWTR#E{oAYh8z(gN4a1z5`;v^6Tb#0X9S7e7B?-ze) zcM$UT6Nc4xwZbplMSMIMBBy00kQH=<7dJadJbU*W8E6oi;$*j`Hblo&V>CNTk!s0d zdodw@cw>0T5^bcQb8D;W{Fo#(S!Hg6b zj6ZRKdI1FrP>$w!j^>yE3XlK^@QZOViXE6Y5Xe*nu`K6gD-N-Ps#7Kd$AT3mNH6FR zvWRH1dt(w z;E^CHfl@&;cSJaC2vr`bSL{J(4^eU0W+2|@kwrKYtR_2OwFn*=Y6|0#2(W(wA(6be zZS1jl1{N^8IFU&C5;7?O{-{Sn*?3w}l|tr`^*0uYuw(+jX9_iuyVs3M={m4<1v2S4 zG#M-!i4dn&FaJqM0B>nWNjLyC2$6Vc7LY&&e94#5Cy9L-m}CGm0uc-G))t?*5P#Vg zLPdQhVtoX0GCc;0{YMt?7!d<>lD9;Uju#;h7lu>DnUzw3;W&)faU(|bHS@?7Xyslz zA)2menjC>k%w&v5Xk`>3TvxP}XF-}fA&!c8nT!LPok<=FK@k;sM1{jjSd*K;=zWm)c2gT=E19(2MZ}OTofgcTxZf@BnHDNLt{X2*3bOkOkuT8|!I{ z4B!OmX-5x$0Q^w^3E%`RsTPDFVLc%L2;cxw@KNnVoQJZW-|3!|f-zB`01#pT3-AQ- z2^3nu0RIPY90PCw3vdM&`e=jz1q{%OPH+WlsT5bR02?Yh{E4DZk)itOq6h#5{~0V! zkN^dsH0J35R;e0KAfY^3q41fI0qGTXNhMzt}R7&1S! z5QljIQ5qM(=@r7+f>O}{S3n3fc}2N6rnS&G4fQ!WIU>GkCbDTo-W3rX^-FYRm62B~ zuJEVi7fmx*7(1b+V8w;o*g;=`sCY4_{Y0pF$);-IriUtP193%&#eoFjoD0FJuL6+K zsd=>kr-K>*cgcXe;-sp&s;o*{P}Hih8mqE8tF*ckP`VRSY9d=&V?~vvCNg~rk$qlD zng5Vl7LuALWhpx!8Yov}m6{5RwxQ=M`Oj=x!_8#EFEu&vuVNfuYEo64y9RH8fS z5Y!5W)@TyVnwpk65On1>eL5G8>R%3Vs^oU8Xwf(@If97lY}|@hMMRt85)qzih@g5^ z(K@R6SgQAV6Kq$j5F4=)yBFhOuM>N*7@M&gODDH_6S?XZyGjrpI}n)&tOQXCo{+Mh zpj2Rrtzs&!PS|RVcSXs`sQMZa(`qsE%CLnxW{R_#m1#$*sESy#hp>r~_qnbM@vMmo zu0orNH!2o8Tafjto%nhdH@md`>azj+hR4a8reUoJn|ji^uv8ngUh%LSyS8k*vHv31 zws0G_ayz$kF|r)-v278u17WwdP_k3vAZBs3wV(y%%1xJwob38^1d+80k+YXFwF{vb zcX@Mhqo*#L9%6U210lIRi+@_%u1$+il>xc2S+#+21re6I5yk+l+qxGPVJVsxf?F1h zOAt&;xkS`wUK_3%^_&MgTnX#AkqfwF!BIF!x5%5kJh(T!sl3knywDr5d>avXdjWbY z5Pa*mlmR!I`4ddbYYLF80Z>0Qo47x_xCwiVIxDu1YO0;vQRS$P=g5xiD1z^r6|Cl= z3$VY-bgrBWhn`zzpo^R7+8Lyak`{ZAW7e=~@x7Cpu(yjH=s3Z+sJpOY!T-G*w$M4Y zo{4Ja+93sNCkh(9BwWHPs+wASzBu8;O7S@`Nmo-T5Tt9w0=om&uY_F9)@&Apk$Bg<&D`A0dSS>4v6vUI1Pc)h!kU;QD}9~u zMp2u_;CD^eBr4%nB+Ft;)cKjsY{yEWCt1LewcsaOK$IH%yGx8-Ke4+&amq?@NqLxg zo?OrYP>~+|c%k{h-|D`f5z6T5Rf3U(&oawo!OK{~5)p?&jnmNAbUX3jxj|n?nlW1zPH>H{2NmB-Gvu zvsox=nq|9pN)YHHF`TT=;dm={c@xYVyAh$$S0rqMHeJDD0RIKh)&(GdU2KCCu_l-H z$!9&)AB0ZCE6bo^){-0;pXLODJ=la@*iInO4NS>XhCof&rU*Sh8pVqB;?`{~F@dN! z39ysNJjdz#%nLC<=Sqx^vd|;Jz(#%A8B2H|joPf;+A56H0|5phlL2CoGLW!uCPE{R zd;vJz7zRbw=KECRF#yd{2%po?5B3C$;3oz4QC;oX;BrrC1JjKSF%NLv*v&)@fZf*( zk|RL?tHs?Vm=nk13U370rVA9|rdP=$)ZZQ6*!@w-T{eW!+(2s(tDS$`eck-E-Q4Zn zb^+hljiBQ;yUX}2rAJ&3a3G*CL=rP_=;uu5&CG>_aR2+wTJo{q>B7mv%gR^n6_<9r z<`EOFUE(Hw;wYZtO$yw-^;=uPyFI#thTssSxH}XpP^<|AEn3{&-Dyi(ptw85-Q696 z7MCIg3KTD;xVMz%@;T?8d%i#1`w!g7Gczmiyfewx>}T@MTHnyNv|<&f)$qrD#qg^r z6Wu{PaOweZDqC$EUH;!|gvVV5#ufFx{;+WS_&l15%wK9s8%fc)&QYApQ(X;# zo98WrRk;5B2&6j*mOcnI9+VIOe{KU!r%(4C4xh|(q^LxQ3K=H#avNdp?p>0m<0rjL zD>TjZpz*MI%S)90PKbx>Ykv6tj1@^C9a11mY_?^uoQ^V2ZQI3H$nwO}+I63;;83=f z5oJ5#Br5wRuSoMT9M5}WZLJ0DH zLHf-WbB?+CE_l9Qu=XCaye*Mjz>Mzw_C0q{LJ8oUB)GdafFO zIt!~2wmX3HxVFpmdC0MdCTzL>!A4sN$yoV99&YCT!2$``e-(wlRDawC{OZ+?W0yWjA zH$(q0q@bs+^o+p#FZ8t;u!YD^mT57T($qi(qOpfKN`+7gFcmz8SyGDCZ=&E#k+f3s z-ej<1MRt+`JVeGT)|3cM4cqer&-}r7BKQ-^3?bxa9&rVc^4|i9(`fKmI=M{kpRY<) zbEHG5bPlyEb!tq9Gj)FH)|&LZ$E4Oh(r>hx%9YE~JvMArG2uMx5cu-fACeSfX9C3#+&V(Z_*q4H67AMfq-Ps)aQ3~>ceIGxEK@599! zv(LFE_r6UbzT!^w29_t1< z3bPOa`6qV84W(p^1N?kw_LU6^^hFbM>}ZhS+QGZryCeC8nCS7yY@#~>WzMqVMrH20 zp~gxEuQ%p{Jbf5VHM|PJD&ovLGJ%R9TFU$>kU2z1?fH-5CN+uEVs((zt#&?$quHN8 z9gh7jDgoneVO||p;RR@73U|t=%CMI-zk2y}SXfI{bgx-U{RQSTZA}H%7Hutcxo0{$ zdNwUOdS;=|bPeoET6B%vhM(z~`0cgmnSH<%(YFX^ZPmAmmlHu5*reOE8rbE9iWoYS zm9!c<)eVanxwP%I8oBjhiW+--W^FU}nvoMV@%d`gX5#lfRMhnKkCHaix2MCRX76tI z+RQ$nViSqR#b2Ev)NyYnQsp2Pl;+{|VPck%P3U_dEb0{S3k;H9+ExRrXrV#T3YqQJ z$?EbQf?Ks`f|IF6xf+7^g3}cMossc#jk+_^G22#ad0v}>aJJ5a+5}u!kl2&aNDu_~ zNrrX2r!}yTlc@W~F0WF}Nu{U{OTxLq$#950u8C!cU985c-R0v)<*tT>ZE>U{`h;mM zcdnN>%&t*B(#^RaoBgkKzJezMr{1dVvMWX+8;(SdvLF}AH4o!XG5Q?u>>fENr%Y2Z z{N%KoZE9zGt-8mHYBO-aEL`d)z)P~rGiRyw>=KZ!b@ePdTZ#lYXzFYdv1Y6JKL@$Y z;P@4hJl|mFn0OP&k!JH*`t9*oS{q;~wb7X62a2i$bUBp{SvQ(%Mp%ra}@A}^qR zKu$`eGM9H0cf=@bBclJgXow}WM68B}YlKXb8-@Ib+?9lR{FSE)}qx_%^H#4towm=G#sKPRsjvG7X1Ae7s_-`qF`ynECJC5~fx z*EerPZa$hS$AU~sbGA~*cOSzLi{()aP-d397_E&sm-Rr{aOu3}M81wtGP#=dZ(JhR z!peVPk!ZnV@*|alN0S{=Z-oeW0*pQ$b!H{xx6=KdY?eUgh!DjECXCd7ngpDSURzH- zzk2Di#Pa4M<0X&TlSIRjS1e5-)WRKTQQb9Pa!x~jq#HiT^N=ad-p|g}X(qyae>0zl z!mx)7&;JCCVlyUNy(cc&1V4;m*LET1g;cD2hlj-#z`ht7d^sv z!c4MbkyaUklZ6a>5{_CGY71P%t>fz1ZoJOG?jiAX9A;VmHz#Ks38SO-!lL&N;4^^x zOBJ3-ONfi3HqpzrnrtW}+8y(XhYK|~A%MimTZ|MWGYrI%M7Eh;kJ99!tpj)roSnFV zDla(=)81=(v|UdrEE_B@`i69EkVVVyC>Z@&`r6yppWy%7Pom!VwoMtoRyV0qzY0%R zDX-}}>>eu-vDTVZ*j$qCD@HOQgOQ@~x^BCZ3K)xGt=Xex*1pJs9*eLJ8iFtji2_Y+ zHYmiRKNUyY1Pl^0mkb#hFck82l*w{#Ch6k?Aa7?Sx=V*R99zb93rgef>mE;bSa?dC{FG8dCHPdcsk*b_=tb?~S=+;j~VZ;abne%`0^i8j_D$ z6U;%U?G>G_bNPOg(9dGas}ByQzxI}y$E=MGX%`1B-m?5l10!9&Oh*v?T_>ba8Y0eh z_u>m+Y20XxBz#Y%2LquX4~Pi$xNMJM=TG@?gAj6X!&QP2JF&7^XLY2skA#b4=+hq% zD5bk}ZB{(U3?=R-hvwVpM|))KCZH!DmumMyhsjRnHA4GeLaRb2IiIMrwsf3JA2j&L z?E70l{I}nLka>Pc-pzu>`dK#gE$7?x-+I}fl83Z<_EL2fB!haAB_k>)v^`qxtW zBD8-d78-j9gR&Qbc3$u6q11-j>d!G_{*+X{zaMS&Q&V(ES@A2r0nJ3NFRu8q31Kc} zfO<7UzC(|+x~|kviJ}H+ZtsSP&_L)M0QPL*fdt{suN#rpS`5w%=xLCW+DRg$9}RmIEo=a&)4%e=Z$ehpK9e0x!==ME7lKVj z89Mg$5)EYnPajq*0ev9H1CzmNDEaNsO+o~c6u>v68L50+pfMo05IHIo_3c8w{%)w? zZA6rEZ)Uxm$e^6aH@OHR5;J2V^X>s6YFs>!yy0%N-a?%I(C7D(L=1vu?g3zWXnVtB z=wX6fE5}HDd#fyNRI4l}hCVPVuD})&(eXASxw1MR5X88XeA`*$JIR|@-d)=s8Ql(6 z^(IO&jwl93^+`qz8AiLSaN=IcG~8u}Tq(59em)8u%)uDH@>e2^RB9)Qd{!N0jS%kD zM=8eJE1nBLgknn08%D#Cqd^$eNt20~q_PysqpxWqT`*z`LJ~4#N~C_#r~DbML<%PA zPvj$_bBE&cLMA#V2^y{AKUIfXL-QXul~_BbbfLJNXkv?Nw9RYiL$Z9NJ^zh;U@g~} z;U)qdEEjRm(GF7{3z1nvPMpt9v<^*f0uur}(K80hUB3e$sJD(#@AE^B}Tcl5PqYoHRV@3sQ zVDnS*9&mNd1<$|CqFS2aHU!(1xE03+|0d&>Bif1{eS8R=>u1zdOPIB_e8bcYYkM6DPaz{?$qHVQ$^^9Tv!vfyjeJp(2l26C9IfCwPMnM zJ(c*PQyRQz*Fv%guq;g`e5yKwcb2Ag+n7FLZ8Tvx^oP z7v8Nun>o60mf9(GBkgqwi38={3YT^8DfQDM54AnW^dWPtdFF|KmKV?L37Kidu8Wg; z9DuOvD1`k?P%OkV73_siv(!n09f4*fERK%@F$oRcii%KeDT((1=$#cB2KD0gF|NdA z-oKgS5r^dH2l93#mRSQb?wFEq#@$+$3wRTP@f+K&2#GaO+B7(UB#Fyp7#-X{amp5> zxj(%^qXa0ZV+L=BnQd!+*$oBl@Lrz@??x9G$X1evyHyN zc(epR=Gn-rYMgIhaL~<1UGbs}SGzQ>N(7uHM}#1w8O7?}GjZSof7Joofr0o>MtgwD z^z}M0C&E?(74b+8d|0$3WEs;p- zUT;5G4?ieRxyT1eZCtGr$OKBst!Q5F_3d6q>`9>@42H_HG~W#qHj1A|$x(_Ij2j=! zfjo_~kP2~4X?sP zLY6{zo7Hx^H$kW9F_06zQ4W0yJZ|xmT0KW&jJ`JVN)Tc)yxH+Zw{a_;O=L$%ey72I zJ3nIk?D$D>LL)xiaOK_5_^#zAliDKx=8|XI*@28X;7wujT{zorvHs4CjTkkt`n+bD z9=ByVQDsTDmBdu!=@pm(w*$XvFi3Di<_5K^F25uDFG58Ab5`@F;D{CP2t*Tq3q%lQ z9bkQHxhGAI!?>if)S;lUv}fXKK^X^ras!@ak;O{eNrbHqD|Rx<%{Aadmhq#)nr%R~ zOai@g9KtrHBm2&_7G`1KSA6U5FFV}H?L7WvFTQChbr0oW(9FC7+to%QjRviUv~(mP z^fZC&Vzw?zKi=(YxsJ?Hr-9Q|c~4y=FbE(VieG1|as2*)!MOT#y)*biUmoNtu>H;6 zj~v8oD1F#?85kGgqstZK+y#q^0MKe}_m|=ye;RC7m1`sMwW2l`4>C%BV(i(QpG0I} z@FYrG7C+KJA5X-8vK~^|Et=KQokWt3apu{X#Z7PTZGbFVvj(xAKR15Y%Ga>`h_74M;K*VQG zeY%)M2fzBrgOD4)25<1{_#ERYd45FAOXAf^I+;f(YNPv4W3Wwy`tEUR+lXzb3>Pc3 z5pm2++6~!KC^0w_yMu~gE(4}6^I^x6oAz%1zGcsb> z?thAYylc)J#k#yr3|wVOkNEA9-fr69Mrmge$Tr=&s zk=d{)OMIZG_QWRsuBU7-mileq%n&0y#`z_ zsrt@o*pDa=Jeb&zNQgWoQBG1XJf&})UYL2pC_r%aOL(Lw*XI*M{Twnk2#@;S&nZj7 zucqfGV7!LiIG}M(9OY3JK}95e<)ak(C`VC5=`+CR(_HT{Fmm2~<{_a6VVk*>!uFQE z1sj}tJ#yX}5&B3}oMpWo-Sl|2E%H)%M*kvhKM_`-cgY;VLf6>}X?S~RdYbl3(M6aa z;>7Oktats~?^?X?((tQ~2z#^+>X+{4Xg#wiO7ozowmXtfK5O~@(RKbY zGuQdc{&Bbd-e3LWPVZva@5D8o6$GRDU!7cEIatorQmRiO8KCe0Iz z#x=076CI{uNoSB-iAlGS^YrxS)xQBg^7~>D*Vbn5I*N2o#bZ%^NDsSnFCnf$eu$_d zy4dVtDMe7(Em$W3L(Kl;^ZJncS{xl%=(qyrSUh;VEnu=Pv|IsG+#dZ|{znZBNUfP) zar#FQMRd{pk1rXbmH9CSKA_9GKYS_sQ_TOaE&+3*F5u7pJ8dvzIsM)0=Re<2;HkQR z=?~!DzJLY2cT05-#b8V&#fN9+=+6@{Hb37Jf$m=_+=L%g%?p!YF)%jk?Ivv>ol^J% zB%S$4A`Nzw*YARFnTnNyeyv~VLLK~Cj}=lADT0UruwDxm36FkNNJI#eJXrYPjBzLe zeKAJklSXKPA-SA>39eaekoZ) z>toa?PuNCC5tF?Pxp(Eo@vqybo5)~nQaszp7pidSLLKxlbSmNuBq5q!!!`o!A8b;AqqKbPU74Q;=vAun&(G zXWv9|8VUw4Y2%V5NNy_Y=;5*nDgL{YxI5eaocz@7pX8sb!>`o2O&%kvw@>N2-URt! zp({AH&-`N|z`{^_nF~iK}DR zD$zpT5D{6upCcPmy|gC#$~R38F<}w5s*3GhnjxFsj}?m0wG;u=4J~iJ$+r8jnIQU= zM6waJ5jZ9YPc4<%Bu5TIgB+qR{Re~aiX#~XG#1(y{0^giKAv|tP2X$ z+=%A6wo(w#8JI64N}jS4%x}1mieMp^Q>yT9$p6Gru&sj@Mm%P?SQkC^MK=;dsgW2T zYwyr8qDKZ=ji}!KlrP&X`1Y494}TUBUh12B-uA6130F%sH7r&{WlrmgBbdi>mJH21 zED&L;hE<9P_T3MGM=xgpw(1LAhUk(mKa4z!IJlnV`&fqAApom1AQit_cU09*eh=x` zNw&vkOPMSoIL4Y4AUMuRSgag0Of}>g5}Vk0{GPy}>-gh*X_TW(<&w-+>+&C}CPX7} zd}tI3YB{cGATfb9M+I@n=n}lE)L6veopPR+ogYnZu6kvZFel7zGSMI$jp7dg9csVEwn zBt}$s4*nUER8#WgH;3fP6JUr4KW+s*Brr)4nr5Y2zm+qm2DPh_ll$h_IQAfM){pxl zVBE!7dsubED5Tp;D>`3>%wdQK`T>KpP77Zfsc{G{KUfo*!J_hRHqa_(46V(PhCV~M zJ0pUr3r1f>LaAdnkIa2ShR~?I+CjxKTwBd`nxXF^1TdoLJcG-Ax-tK~qz6cuV09TK z@>ch`caUxAXr%i4t0ww?wU)#^+Dv50_JdPU8O-g5`cS?Ai`NGz`6sz&1R_bCIkJxS zvdbE^FMn-EX81;A@JNPRhz11{p#zBwYy#GZ=O%{?$?a^G@_<+ji8B>B+wu{C$Z`-P zP`tB3BcbKT8asyU+OERk;9N^8UxP0c{ACwS}*#nWo_{xujT(E@V zG$_Hp)F)<>mA)q*TZM^~5VdOZBLV~%EJd`dm7Is{;)XKeEEz<~(!U&t#&%#A_KL&| zNeofVVCJ22(o;OA5SwmRKCj<0Pp|+J;-A_0->(zqG&Q3M8`7=Me3C;~63qULPpVGZ z49YB`MQW!^QmD4E<=*|uTxNkdW9UM$s@bAQI5C`?^CwU~jZHZxcoeKO{>lEU7XmIy z{RxhYGNH(G268xDn%JIL*nHNmVr^$ema?3JD)_JR=b*^X z45`atIQP#+!VE!yJe7z)j+&S%PgshmkL}^o;U-9qR`oo zYQ8qP?-cDx1y`%C@jkqJ;C27_jS`a~za4x=s}2E8P8$ontkR;vYXA4} zG;qD6;C|g2*{d3(LPqlP8=pvN^kkZxwz<|g)0O?xz#dn{wa-j_1rQ?5Ww-1 zKzTVvl;+VaK6-Rh1`Cyxo=gg9S^MA<9vf%oSF80a{si=Cp%Dr+79YDAS(pRiRF7K8 z0a)#0YVSSG9_Q@Yc>oZuKa70DC_zpV0HIEK1JUYfay5w>#_{}R(lD9#*oo3X`b&cF z_Uyo?>`0uSK6s2&fq_Ffn*e@<4AUPp2rnX?tCk^zJo9C$9JH`c}xy(btdMr48pk=Q}&XVB}ujqzN#8x+wkU5;9IA520#KTEpcYE+m z7b8bzP+syX!Qd;EJl3=0+G~GDoAfsfb-p^)PMUKJHH^@tUXj+OnqwEQu5TOve0i+{ zQ?nxO6Tjm;lY4P&9__u#*zs;7WGB`!w0w2FXyh4!^}?A_PT~V`^=yMhmQy)v7r%qn zs2pi!0x7JR0EMN2#P&3N_5IU!-~q6~q(ehJtx;r`*W5A_fA0>CoYUe@n>y&w=bbR+#ip8u)ldUX9(o|=ehhq zbT$kOatxeI^F=9bTxA5N@6rVn1I!fy#=>H1mLq`V6Vox0uoaN-Z50{h2Cs*ZvJC}4 zACZsI<#i@{p_wmtkO%*pZ%7&PPEt-fCqfR{zri`APKLmXf_*hmtv|<5j11?9Maud! z{v<=x;TUP|GWuJa%AkNOxxc2olNPixxzvUsbTSCa%wbB`kSF8_8ePoT0?K5I4S6UT zscj*fD-*kKA^Ui25ZNbnT1u+~LY5AhFOkYqE<=Z7i82f8Fg#tweiMvyy5B7L_y{J1 zv3hC$%3MmIpN0%h0w6FDZ!w9KFVEwCQV2hLR9FJCpY6!Qb~FuBD{$&<>^MVN^i z+YtDuc*j9QQISQ?u-Gr(db6UK_V?!fXi(EAJP5iaf1rMACMLWgWvH?u&mu zebZGkSGQ^Cf)RW-SRHGa$Fg|!OgXpRM&r)BrWn9I7=K2B_2e)F3f*6Ny#s3xHVqqc z<=L0#2-Cm{#U~jumzJ|o?zfQ1u@ro1JZ+=6um=l~G5cquh_T;In~z%`Xw+Ju-&*R_ z%jP`7w%j2zQ7rG0q;Tc(^2K5>jWe$4&F5C=rUlw4R2*T079s44%Sjx@<8P}0GvTFS zH+|Iq@;+JytG7-S5=rmeKTZ$E7tPiDb%cZ$;YKAyy1USI&I0B(ROH?`Wv^m|>98B-ZVoo^oP&XBM z|9&PCU$&%Y9{JV;g^lZ!H#TCB1txR}L0zDzKeDyGt66i$YOISv41JckvH za3*C$^)y#aE&L-nqLGigi7$)`R&}lvQisNk3+8UfJ#3I4YU1NobagCy?^u3O*|^D7 zxP+`Fmt$R~$3v7ukVt4X{0&-V&jxqzepN3?m;_r0gA$@I3fXtU-A`WKPscOBR!v-L z$+d^nUg93D3+;^~^t>S*)5_0^T|DnmIb&FKjhm_;}|O zzyWlX#4&#zfB`0=S^MKX-vLztw{briM<(BJFaubI$3L1InrI#P`5^7Y>OcboRXf<= zJK1+#Atu#YPol6!Vj2TjJfITj0Muf{@2vLG#}-j^BK`CVC4XA4X2@4-n!umAF>GKs!CD}e+Zp~9l5O%S zIJ_SGP45(niPlE81`bAf`^-+I6Wr*Ofm(Y)KM7c|cqZ$3+?WdJ(9~IPp6NJvLY=?* z`8NhgrMn>cxT-EJ!Tm&pL39ToUR(h}eZi-<7vGqYKUWJDNUq>Z=Z9bm35{^!owJZ4*fs-+oPwYFHHoGl3*%lA(UP$j^RXl31k8{Eq?iK3BZ5}) z{4c_UP@%8MsH{SoEUklyegw&01reDwAy@{;iajwuG{NbG=eC6qidy_|gy37Pr?DzL z)n|~bU<75*O)#7{AqdOY2=&gYQzS|SYA|2A_hH%Md(QDV# zBV2zDVat30?51GZ$zY<>epRA*eMVtT3ZGf!c~HAINxv|B^y=AMv;_|um-;guyGG{w zVMMz3nV~lV8g%m}h$5jGi$56d9;}<*OoG7hx(mf)^%3rAmX*D-hWR+gj4@b+89kM! z+XT!mpCK?Bu)YT&>}x5gTP)~rCOXly=;PoRhH!pi=Y<9>En*YW5u?}hLb&p}PS5mY zL-g!UiS2!`LatyjR|Z<%hO%L9!e^G>qh-ZJ;IJD<{%e?uFR4x|BAdXKBFs_(!-@jK z`9nAxxPeX)K}bqq$=>GqmWSjC07V&VD))Kvp4E2?r#lZW$}ano9Q&FZ-#oMNHFx$^ z^1G1@xN*RCBZY=IB_;#!E z`kSOS+44I~N|3|bfyi)A1giK_{KpyXcSQP!-_{|&9RYs?|5KM2h|JsJ#Joj|fcEr{ z9iNh)TWtmrVZ$A>)c}pfG&k|G!Sdbek$xhWvY)(rIGHWY8&xZLN^UIZXhT(>cy(8& z6mwXX-P3I9kSMD_c1lDIwi~W&NUoM#VOJP_=$~>c`HI1pcKPCQw;g8wqD9mrWqBhx zH22mlZ!PcoiM+gopCdt(Ff_1dS-eC?9Xr(g&$B1UYSNH`4-J**>UCzw8j6r8`XJee zTTFnz9wope;g86cNTf%05+b@tF}d|Ho3X_@wGuleM%e6yurIwj)Fp>e739K!ErVES zVxT6{zl~jQ;|IG?sA&m!xj%{IP>valV)uF9$8PHc{|s|U8!t)xcisIGZ_QY`EsX<4 z+Hj{N!q^T1iEd%T6g_jN72GVr9V@}90|P`S8J|HSfc-*P(>kAB)=D$;Y5@vTj)|AMVqMpsm=ezgAg&)Fq}#UF(iFbpC}*h}7z*u-qw`c=qB z)=qNy6tOvTXgC)6a~dGZQX#&|ca4aXwRk~BITA%^&2&0*Z4?ihkG_T_Bbl>U#a=nll?-X8A^Hj94s>Hhg%xGl0#~p!3GTc zYA*zmtV>bldGK&@sZ4K&`7+Hi-JVPzr>}JupVOr7f0To?Te#@JVjf@XwC8S&&C}YE zn-Ys7KHS87-#Q?_8hfY(+>CoUS&N!uyV6{Px+UHaBHN30f`^GiJiZUu@}U=8t1I2{xZ(pFezAxPQwH=7;+5~4+J@8gQ1lqXPmg~%g*ytqANV4 zWxJ^5FYb&4dxaBxkt%cCIH@%G<3Y*oG@}zA2dW)af_7sLRKmYF{}c&_tW;e%BW9hX{zch>KM2zF6vptUMsOb>f_Y|*2j z;ED#YL*6kYu3&%$SL~8!tD^04$j})jr4ZmDT!b+PdXLCiupz%>;(>gS_ECgxkhc{0 zD*!I{{%TDRhy-FKvFb8fC6f6XMDctnFY`gS|C;Z&Gt3FrcsDw@70$TykqJ~z1zU<1 znAYEkeSWgM6A$OBPe7y77$rlayc1+Z<6)WJj^N`xiCPhvo!HM3Z5OF^CR}Yb3Pr`V z8$2at4c279(9X5rO(GTV2r4GD?AU8GHRZ6~w$;ttrhjX=YK@jVjRV#gt92`kDfeXB zZCP>scHFiVXLQoBlJ>?ih?&d!u-dB1;GoY-8f+w0k`mop99YGS4LPrmi5c};bb>qP@M+Op4#>Ba@vTxCx@3eZLE-4AZE z!7<+=(?&M{yo5Qn<C8b&=t+4$>K@mm`0+0Zg&(ASRBjr-GnLbJc;S%~+J zd!%0m0)k52rcS^0FRnZvkUbhrymcXvX1Xos0;0Y$hKoj)tJ^}J40nwW1pY&5&%Cis z9$j*jlg3d?2qtUZ#1!}hPl18dXanX^;*Am9k|4F>x2g;S2{L50387pp=rS7R18^Re zFwSl@1xZG*Kyy7A?UT?snqX3bHwh68#SvhoJ2uiKCfp&=%zMECY)-YrD4i5bdX}V! ze+~)JCRf`O{gm`ULfidy1f~HVup$h zUvkEj_r6fU6IBPb^AD->4E1*>$$1Y~KVE>S9xs%Xe9UJDaNunwUk1# zmIFC~OwCx=lp@;e0|hwMtHh;JB39NtMa|4tskJF3yu|UK&E;1a(Ik)J$AeD}W$^lza}g3aE4(ZG%1yB_8TDWa`umcoMe-%;@%0 z={CeYi=SjBHJHoPZK?GM7PkClv_+-YF~Iu<&0)>>JX5dd4(}t}KHo*R&?O45*d_wc%WxZ)1Ek)Il@LaB=$D zvDEO`$%5Lb0&9{HQ!x{)cV4XxUChtc_hun%Pbk- z9+eZhNX!tle#e+Grs^xGmIhg2SI-#Nv5nNAowee2%b3va4F-_L047J(gpJ5$#$2}T zv$~8a7vIaQEgHM$Ga1u9t(Q6H*>+N=88h#0F7rUN_He??*-(+I0^%Hdxu=X~0sTOVUyavW6MGUsz{uFBxFj+*hA3ne1g6`DDYI(3* zt=BakIZh_0nO}QuuIqwmoh=BnmWM@d8WMAyZJuVWO!?k470|jksAsJ%w%)Wf7P^{LBRKlZ)t+CtH~y`IV1xNg1eInQx>cbfJ6;pVmv zMCTqvn7xT9de{FLF&g?bdkf$1Zjh1ABT_wko2>0_SRmIU)-8L7_V(^GoX#^bK6{r{ z^!J!%u4igp_8za_?+FV!uZ)@O{by~zr#y1Ka!#{(_IdbNcS~{yT`?zn?JoEL8OG7IB{c@YCG$SiiqJjP$R^)N?N$ znF00$@?KB5!-Q5J+}|1LG%Gzgn4(vqW{hl^8)ss=KY@X`*&GD|L&)H-k-&`f7cCp?~dK_?$>Ys z-S*SJKabD*yC;hJJ(u_Xx~}gknnU1zi@ui!%#aRI3PFcxSzu-h|9f~r%Yr|`@K>2x ze-edP?>(@KlpkTF+=Nh}X%Xf3pt*P|%QgN=VR1+Qj+KPP)MpHmhvW~@a089z z#LY42I{dnHp7e zUXSh6Po_+iPIpd{$3o1B$tcg*Ig3dOpM#n6_u-*IW9oTwIiNZXFNDvl@dn7$i18Kd z$Q%-196D+cFrkKq>Qm~;-x0q!;qJxaS7<({e}7JChTgF}nzD?|NL7)RAV8(C1Kr`a zT^?oV9>gv2pnfrko_;3J(m?*nW30V_rl1hR=ZwMMLlVlQGCD`IrO8>ZVP=j1{~Gt- z7NCzGsME#@X4>}HP^ZWAl#dq6sjHP4;6oGJZr0R#AkLTrdpDQqx{Ac?_U| zju=!bOpGmP(ao6!JXyR3QmFQts5WuP0We_JeL25-R}RuF3vuv z|9tR&(tkD;&&E|p>#>GDW*PtiI6R7`x&zLD1@IbR05kxh#}5B*{=)y|FAKOmdcOud zAN$z>_JH?eANZr?KO@*YVkN*8umbo1o<}SQ@IPk3|Lo|;zK`i<@&Dd|JpXI^_#FVG z`cNoT*ZP$)GuH46(1H#fJCkdUOLBm#kW`SPWfmX@)xv9-0ev$M08msdbQK#w5JBZ*S4 z2qRL8V?c&?P+n;GrPyap=~OP;G(Lw6A?I8v?;`m(fAXr?O}=js^c=vWmRJC<6zmfPDETXO&uK_y}i9% zU0thj!Ru*JYblZ6vy(RSQn!n<2E!|cqpSNvN+&Z~CeoTm6Y6FQyLYRL_M5Bs>dSt1 zw;cAh=L~0j8b~SloLe-SS29*mJ6%~ZS=umH+cMwSwbb7IwF9}@`)ja!wRL>C;d6g~ z|H#P5(9qEM`1sV+)a2yk@cQ7`_s?Ixd|6yvoS&axU0q#YU;p;)+tCQ}czoz|dhC3D zdTVfDfBM_O+{V?$>c#TH>FmVx_T<9e{MzBSm4mOdJJXv-->k9_MiI|nM6&nhNqbY?P*G3zPKF2f2M$srW7LO%!XjK}IHI_`I^IMH)D>ao)Wr=wm zu8lR7&E&y8LTHtn%jb$7HOWlIn=9taG>VjSlv^qntMr>3*T-9`zSfx!{y(&Vl_nF9 zlm2b)JL5So+iKUl{5fmKC)(=1_XVQk(y6r9Zw*G^);Tf&$Y8Zd=9jrD9gTYvpM;z? zCZ9W^0r?=B1C`F^pY!EfRi;y&Ex(HJWy0T|b+#UVYxnxKG1b-PR@z5}AV+*f(|Zp!_t}&-XlXokz(8VfN@y(ajL3u6=>4wy^o*qQb}j|AQ&Q z#1^=)z-57I)Sh>d9(juFS?Ek796K?>By17ru^#?(=p;)AMJjmN6q~Au12EO=K1TPA zs23tXcat?-<%U7>hl(&dO92W06EIpAml z{S%}0YRT!;DTf1j+zZ@Q5VsewYM8OtplKkh3|oy#h=oESKRUY#9Eg^!)~YC( zsaMm5x#dRe7UD0j*ZqG?rH<%_qvT=4pCK&guO*E_S`*HH^H2{NiZ~V5@zWCg_|*9m z_ea+oyV~FTN{O*8pcHCr?-h!kj?MA4*V5}~_R6))v-~B-B`cIshGIY3f7D8-rCFK4 z4zS-%F@7N=v)CP5>)>0nH#DtbKI8FNId=V~`}*W$*{)7XscN*>4QOL-R$iwW;7hz1 zcs-W$6ZZ?94YVsN_SLofv}4wJRA=AAzrVL;bL>YudT2*}M1OxO0#KaI*OXFt z4a=;;-F*`5fym&tf~@lHy*`3BXCE^2GCb}1uU!;A$`7n1Yum9n zw(OGbYAswlGI#$8Itz!bXk*jBQD8zTYo6lDdRc6I^Bf!rsk_Fyu=veD&GXKpp5Yz zn)%~Y7dY&~`Jj){BgATyza^TdrY#opa&ZAcMv=EML;n|D z_u0N|Sl_E_wh?mlvD}Fuu+0q%)z;h<2hh z=2chT)rgDMH-QZs(q%z-)qU|%vn-ET)TAcSbDA0cHseC2@&(|Xmh7cT$0RL5p-lxI zOeqfkC8ef7Dg98VegQ77jjGDN$u{jm>$5b2sy$Y=@R1_NMo(H|E zF4cVlvsJ7sC4qx=Ezd^Z@IGd=#N&7ev4 zjal^$CW6`(H3FrYKVD)DQWTOMu(h(o5bjI0mm zD0R2$dER-Em7%I$>pcU#`HFDD>lePHLnfSWS4$ev>*|K&bLIK;_M&%P(?Iz$2D?Ht zoZHg#jQ+(yyYg`)ZAdWzE>KsUN)rvuXH0Qi*pC)4j)a<69l;Z3w9g4|0B1Ig8tNJ5 z12Y}&Ti@_*$-~R(#yRR9lEQI+YGH?a_@NEzX1wI1)ozRE{%;xAUurXK?c!b2+>_&k z8w;3xiR{ssJfXPMx^!}*szJ_fZ)XW%rnUZT&aVbSEH&ghymzgB@mKde>TLdoS$=}iqQj8^$cPaUvu0^vjR}^Vn?=N2@*$3Te z9$k45L^O;1@5l{t=u3)jNwxyFt#j((G({f2vadYOxy4qpYkw2d6z+~@wp}R$5&qgt z^`F}Z=Fo;J<3Aa)W+%c4Z%YO_N}Rrr#K|%_ta3e%WO*Xk3)NnTGC3)aDVxcY=+TRc zUu?7%HL-m^%cIC-81qibT0srf&C2EZ7<}TgHTP?Ujp2e%v~)*^b9c_MF{SH9^y7kX z!nAbFMbo=7k36jOa~$RphYw0mWNPE>B}=ZKI>lhr%ZKM{u7kR=th|+2qwBWJD>;4L zgJ{Y%&kAWsx~ODx{JChqtKvCINF&1oU>{xHPGX_X=fk2LCGAf zJM&~KJNn})wIB{ib$n2BH(cG#0-dhFAR8M_0FojQRW+v+LN<%sR4=~|bsoMp@I$|Y zt6$*|f8u?OdLTuGG)t5%V>wiwOVMH6(XZ)wY&#FuxlqwzIcfi9#*Dsi&Xg* z_8XPDz_Z-(I`F$M^d{a|lFI%x6{+j%5f&_HMn4_7`Q&z5X-l81tQacVqYlD1_^v3c|-9&vDv_C1C{sspXNiI@Hej+?#VpGUK8e z8duQ_Txx$Mk>54u?vU{e{DcZ1iM38Xq%PlDPF=_iX1k{&Rw?9~r!CRLYJzWsf95_S zy(#fB{a^4{03&zEIw~drUcjN{W(g0O0UTKd(ZcL4VczkNucNDPw{+TSA;7eDU}mX?{aan^iHLOM{tuE#ZvFqRC1~&tQG-K)C7%2 z~ z;^W}RSCWH_>Bs3z?0##{n@bJTjSQ7aeP675s36?ZVM z&~sDZCTH-(R~QbK+yZw-kBi=(r)ZV;qw@(ZhKEx&`xAf(jgZJIo>WJkXDa0I(el(q zen&ei*ikThZ|6t!S!!*X~)(IIIK{#Gvj93xQc0=Zs0iZR6x=O%f&r6zTn7CK%q5O!7-|fb0@1 z{5s>$+!Rpo2Busk)_0o0e^Q_rmG`;aKBxxP*=0ixC;gV|#}=8UNDn~qN)?WCeq4gh zR{HGuC5C;5Px z1eg%ZK@BYWV?L||@BIT-x9+w&9(LvOpjAE)>_e&m#cV6Uq(&vd94TZb&u;NQ7b}U& z&?+U}$VC0JbH6NkR0$6O6gX}bZwFW~l(?gRITs0Lu?`k#Ljl@4a7GH|GlddYYtf|m z3L4HAYD~d4?_pOMgVrXfHli?45bn*)jCIm#RVe;4U$#n@Pj*r?MGlX~m1XfK^%KM|;G-g2!8pw6t$64aEJxABQ;{xkr}mX1W&dI$ zbg<$bH|#~ioi)BPQ&-12sDPqrO;|P(6j^Of_YxggCmmSw$?5??v3bcff&G^64JW~{ zZea=`7?YAqPdtnd%8YY`-DZhrf!4J604$GFykcRDt_e~-#S)s;0HSd|>t5}R9_V)H zv%e>bfpe|*waQsaTDBztlyF58Pzbdj8oKOkcD;I{f<&n&g(XKz=(;X+7B4lup~)p6>DoPcUq~g3wUHO)#e@y zTxSSZ@1)A^3V<@t?!`CsS{uT;2qt+!dfBvTg)to6+q0evd;ATd z?D{J(hy7fd!Q7X6Fx}8{e4y8&S$rv|8zlLpTvK5orXEZLc7Vv?^KM17k*OTx^}Rx@ zuEMY{!XC+U6ns}O8bV`4Y14LEyNG&kOBx`utY@7vGhwc7^W$?;Z_;96mNngk=6ePj zbWJ5EE$)^%bV;x(J$tQm01lRedfWPk3xH~ZuJ#H)*Nyn(-zU%~NDc+eQo^6qz9RAI zrKB4m-RP1gOZ!O)cy|g5g{I|qKPH(i7252==e(GYe7RI35PY*wnyHXPvSm9GN0K&B zn+MZq69)m5kF0ye)B0vHu)W{%G$#ECVOGLS0RGnEk+2SZDrQS03^r*OUnSt82-DTG zujP83Kqv5H`YL ztbl)Cawt!Gj`q7r(uUTr3@o6*K1p{Bl_|}7Ir0|ElqO;JC|hItF-CVfiC;QTq5RE# zFv`%0%9T;=a6wxUmJuP?&vtQNZ5UFiC{u*BqBmN2H0HMT%V$CDn&vR!gHZ;S&9%K24ppeeMT_N1TUZ!mRuVQpO>Ip<_b(3qS1 ztIw@cq-$I#2xA0`=63aXdux47Rb-!+o@?@4Ry_Z#K z;kT6EOpW)^@9X>GiL1RP#=a3@S)*S)!m}UVI%rD##>GiLVGm%Xvn)_cAIV3MSBov1 zT4juY;o~6_D387*^0c{`Nf?BU`Gdmj78=H;GelyVX~75y)%Cp^R5H6aB3#WoG%p#zKQU!HB23jg@`rq0HKvBrXDsvbg;#dx4To8%*wgJ z4)a_a@7FI;rG<(JQ3QT4z4iDj72ti(B-$?f|QPo~)Bzd%wCB*8iI;4{Se_{UXof#m7%7UqLOO?XKWq zJfB)6z5qV8dm{nk+hF0ADc}4FMM9In^a#b^(%glRjI-4c+oFoWg#&IWVKAoLb{AE1)2D7;C*sD%w*)ZI@n zYCmzFW^59E50^gNXq+m4>d7N<&?T4GXM&Yb>l8jauSk7Ty^n`oPyw6+xA!jT%2jQ6 zY4~wlpNmbxJl1x|;0MJe^ZBgdKpMbu?+EejBl(=?Mc+v$N_mW5IuylOcg7sf#cH9rg-E3Br7!GP?Cq#Mgy9xw0f!WN#y z>5hr6yxmSPEgNNLPEDLro1!B&>TO=b_+j4~$0X^um(RmttA{<5vjaPWut|13>a_2- zJ|;&Be|-WmmcDa@Bf8z@5og);Je2ohvrqb%DJJw+%vZb7wJ0Qm`ALD1sM=6+<#e|& zmcKuPy|_;*=Y`n1tEitIug~e&>w}sqLv!q^X^WZo_W@O{_Rcf%OxSno6Kc-S8DTKm z&tG+DnNyVxfx9Jr51mev>be>m+IN09yoU8hbkhu8=oX#D8r?n>ean${fg?VX@`C{z zJIshDpZ7jOeHx9_U?u++rDy>OYLpa>CyCv{nQAbB%f%AgpA?d_A3}?bR$6E4XDc4i z0sBXT{+>iq9+SW?ih)IZ4FU6zFHe8xMSSnd{?zuTG%e-cP7rggsC!${=NLul(}ACqy?*h`s-$aF=g=_{+*Fota4$LAb(?J6q4jl*`Xk8zVgG57rp8Hzpmyi^sme0u` zOes@Ev^g4z!o&ukjBZkzJq~C5~{fNWK2DC~xkJGmg zV$x&iiiKv?=fNS2i);7I2MkJSj6Sm-pF%7EBe!k8xfE=kk45oHefx+lFRrY4ZASig z=5mTl7x<_`{}f?%Qc}YrQ}}=w@$b5N{(rH7-ol^QCtSoPa_QX^5^wrB^A}>nTvSV{ zja}9Az=@FZO1jV;mAtk`&hk5bbvm_V=JZ0?MRe#P#~H(1DnAYHT)iMUmo7r!xnhQ~ zfU2(WDc{<`=|O94>H4m0ENXKX!qY5;)r?K;-PMc-M~X^_bGn*V*7&=+zKQ!;Jk5<) zc8CX5sOp?na!NmJt+|y|dfFd}(~~e(C+BT5)*#Yq%9v>0c+4QCN>Fyy?$S>(t5>B> z_vbwHOmAqe6yVu4&8|<{89d+;!tvAH`URfLK%48z6n>e2^yWKf;peiMbpxc*yE5Ye zqBl&_swAD7jjOkK_Okfp&Rh`!leN0p74` zFjGLg5C&MGmQ?vkRg99G)^fr@FT-ct}o*E(U{uPzn9x;4Tm)v1K&qayXRvx-I*dSHT>Vp zx7S+j(j-QY~s^j=_mpX{ZR1kG3d*DwT?)RE`ug$dLo64xihoM|*WU zIyi<=(A?2|RKc!^c_;O=Im%baL1&v4Sy;LLmXj7-XgbZv0u&pL5!vNHO$Me{=r~02 z=M^Fg!Qh(!chn~2Hs5&q;~($-V*^>g$!jY@p?Jw2cI#Sl&E}gg zIpF?Y<~LGGCpP?;XE+MY z;gzl%x0=Q+1;Wf(Ayq3HMJ{y{+f2F8R66vGT)i1LoBek;@e@)l<2ck9Climoc~W*EPTM{Z@3kTcK!PYw^A|mTp)(pMZ@I{g%T? z!D(5q0CRTL57Pa(sZ(rS%c2$SBl6~}mHK`azbrxd?d@uZ{0pg(3G8!e}$Mmxv zZTR5fhm4=?oE0i)5th=Wgu9a5k}{AFxs;0yNtZnSG2@o+>N5M7{W-0_LC&OnN3z)f z{ZcMpeZuc%{kGt#41D9R-Ie|!VKup*X_g;}0ljUZ80m(Uh}ms}R}#jv9Y1nW1RJG) zj$K`hyRWQkN#SyL`r+dT3}R@jsNRQ6ol7I)jod+ANWgcCk*07ey=WkSEB2T^+g#EM z&F-$tz_R(8Mv&;MzL{8=fc33OTX~y7%{7yR=;RW}tke7wx*mm=<5s-*5X#0i=W=Ll zmOMrIzQ^s;GW6T)H0AMhPULD-=ABm_Q|MF$+~dO^j7f4el6C3z((%>ZTz6v7Pla)7 zIi+Dk|?eFWxHS@yS=s8C{ z5BPoZsVVW2d5li!I<6`81G&O!!87WfIDuu3a4mD^96hVnzP@6b2l!BhFKZ8!p7X$N z3qD);yPVM~F3T0j)fkd;(}wnH@9kcI=2TB$?0V(&f46$`((a|XIyo?ETLC~x-r|b%Jwo2H<1ROl z>x#7DoaneB5&$0^`QnSlDBNLR}ffikrM`_80-#?5+T(sX_Mar;e zncH8g@4d=e0NFKUSIAfbh(C5ifAfxa;*VZ)g}J|;EaACzWt5dpw8_77q5cDg?zIe2D@kpg!>EzeLx0va)#6ogJH0RJ%C!i0 z8uMdLl_1Gx6f$*;kABNOniqS?0%=iK)LQ9hT^MBB9Q-GU>vU_R>xp;VA1GnT9&GLB zA8ef|k*gSxXvg+N4k*MUkT0x6J%K&H6KcROq>6>(mpE{p^jNQZc&SK^3Oqk&FOrBe z?r)sw!Qqu+?c}4pYp64kMif-v_WM@z=~YaijLHzHKd%}>DGqd-A5c(fr(~nQtN`8Tn#f}rMqGAkE1$j<+X7fJ^0{Z^H$|~X-JT; ziV?kP?7CEC*uD@m7~9xVC%8Er<1ilUkN%OELE0ss?u{dA9yIdRzM`_x zTmn_7fC1s|kn=<_zdkA$iA+0y-tdHgIYuk_)$xVL%dkR9uSO?VpwGbAt^^$EKs7)B zOFHu^cAa4Vdx+~-;k+>A>b@E&Mp0oi-aE6GKa-;b^7e63`d`1-NdRge{8o8od={^N}rtasNP0#6?eZW$GE;)de_XWl`O*HoUW*UUs!^JoYtu9-rSe z9E(Td#z!zaV+WvHi7&=$$El&q&{yumG3cbqozb4RRk2o+k%&RFUR|@dQ3CQf?k$(rauQi|iWxbd_s)S1)~Lq9PNb!HOp?Ip8Dv6sl+C0QfOE9|LBJ zvJac_Pi*keRhBAxs4c55u6k0Ff!huDwtI8>@O-+hb)3ylv#|@*N+lkTHS8xzJoks< zv7N6Enscux9<5AoD?{6JwQ)ZuW35o1R}8)m>;7G7%r_oybVto-Zli*UdXJ0^Fm6WkG&0_>5E6@2^gd45>AHUz9AF{nU=O= zgBI&IH@*!d8Jk=PC$A6`n5j%A+R%%r#2^s}F(l*7CO5@TA$`uw_~qf875%i;KaFG7 zjoWF4(mwK{qSbd~==(N}aqF^i$7r6%cn}YS2|Tsye#3VHQZhjOliBQc`-0xcf-m6> z4)CgFoUa}>tX^Rp`?I%Xzjiv>)R$^vZ8(9CO_d6jxXcY<<5ka_X-^JO?APU9HGb1z zXO!suzOmZS+u`Nkxtb-@u9-h$Mj?20QmkD8sZqv!f3)xomFHA%bT?qU6+?=Ae$O`t zp;s)6xZnxQO$*dFrZ_vJ)X9awfDb_dWq)jBT5rx0!epg+1&8pE)uD+PfoU5CofL%D znWS#(ILWO|sFSE=jJE}E7)4sRgmfE(h$0nrRH390g=js-8;IVuD7mvOf+DOYOvupL zvLVNCcfB6RN0=`}-dvLO?Poikmw7@F^4;nm&x``aJ3DHt#C6Szg(XZ^bF{8OO0Gq) z=5o2Y^`QEE)XjmGE}SOAsQizF3cBH)I-^zit$2=)zt1`L(C=#zLiNG=@zniEKi>~R z^W%GO2$5nZ9UvUMkp2TG<_`X~hE1iKu=u7rV(KVTwZ8(S8M;?(W-N24=|kr zBs}G&SR=*OZnl2~Q!16;H=i0ZPLC(Z%ti`yJ{Or297%}ziyZYB+`z0M+Ie)t<4-=x zeJZEnn$!}muP6SFW}ma2CtU|Hts^lpu?-Sn-VB$h9xh7jxUSBWbi4q=CvyoSS?;+= zz?(lRkkl#Z^}i2Drat0>8TOp*OnN^}4_P+!J*$6W#ZjMPtoPY^SB@dsgzvA$BW{8{ zqpgiW4{5nc>Y&YMb9`F^M4 zB1R+F{k=uLZ$1NWFivkvjFn$#qt=tTt#9=|WB3OZ^0o&+tlulIgh45Cs1k)q0TaI;QH_jJ$S8O7s?b+hg?K2K zm(tiLO{PymR4txIOc`y6KHeUp=V+@k2Ru%)XX+49`4Va-e$57MJ?_}~ED?6Ic?ZJ~ zt|2KF9kKGx&qn1J8^jXz*vg|oGsQN3JnA^JN z?|rs>V14CJEn!F?DpV{RHA#gYeoMS|18oz{o3>ML0z{e6`J5D7e6I|5UP?}l%KC58 z_R=V;e#SdHi%?K%Uff7{(n!LlwO_EZI3k+6m~;8+*_i&Q#D0axXu@)R7xSmJo1FPZ z0^6OMI~lNtfqg5r;}4R~Gt_%FU%q($8=-F8|51yY0u_j-WQX)GxX?|>y2;|*l=ZpS zNi<1pk}LOnI`(5Z9%c&wBuDo%e(DEC-%~$s>aKMC#&WOa3B>E-23*?pDSS?mx^-vD z%`isdsr|xep=G*&6hpy5s`EPG`QyZytp#34UD#HyaN>0G%gF&7p7!mN)dictM})uI zzjtaMRMJRI-Y3p#8I6tH%3Cr_(tHb5aA4YXN`Y}LJ&u=9j`!)`-;O;@s&s|XeHt`3 zt**9cC~pd~FagrJ?-j4jh3uI}Z9WRyj(6_k%D3QZZ=aEcaG^e>Ho1&z%*l1&X+7E2 z8z5~u`@){P5sHbQ7VjH`^s2|=`)Fhot{=N{@7R{UgAY$&_BtJ@)MRRgQ@h1AZIhs! z;-)r#7c-{F(yvEANVf&RDTfS}Cx8^3rdTz3Q{UmEcv&Xdo+sV!Qr=4Ii$k;>s%Tni zBZhf~j_5G20plcZDR+1sRV_Hbn+#D4&wthCnQ&{>=(i=+U~SVcb$+^`Fv9n;wdtPF zMWXrj|Nn#u@R>yGt(1@ReY{vQe&~X}aW|UcHbhdkQj+p~dUSuk zlUTLWC%FqA7si&48{PjJ^#_Gruhue7I3Fntl3M#(GYy*X{<9{sGPz zaPw#B-^H!&4$yJWdNJs4N~f~C{uT2A08tPer(Jk?*=8BWJ{9FgJFtH8K1gUtTiL7b zU>7q^(#l`QB>+<7W;@Fg&+y8-b>b`ZybyW4yT9KO;lPapAVPd+Ck_<^dcl>X5ni2R{| z8;uKH)Ybc9pXw0$UJSwz56Z9mIjx6P_QsV| z30An5HIUVjrJmD2Ja5+~p65(hUxsXFJc;Q#LmNJkGG*?MfE+Ln2}|HoI-UTk!(#yu z5a5~(M0-cV$wAaoV7ub^dVDLG)OjftLBdbL$k61RHozFqMH|esv#!fP4$`HmA3x;< zka4jM)Ke4#P-%)m39QF+2sjsoE1dw3Z&u`U5G$(>GFlx}B&)uc^zdxE3Uk+%{U^^j zejyzUJ`r*2IH*d8IAUJCl|p2;DzCJlW&n|Tog}37>G!h5CP3OPD0c72pSqDvu{`{4p^vr4OdK)2g2uut=DyeLx23Hk;XeZ+YYVhx>2Y!_}Uk zv%~Md<&M`0arEMzf8a41lL39-(YuHwQx*|NdyK;qJ#!)*Ot-Tan?ws2zYJ;~lya%up*mj%OsH%+qKK^%gnacc?#d%)S-j07%wZxeZ-jb9TBj6$yJu-te=OD?cwcJ`l!IEL(?TV&8y4}5cKp_# zdKk-X3hcC<*gIl+KLWJz=M+u#Z``t92qD-TDdQybKd(S7tfsMJF z>jz~9P$tJ5Jt2`7dXM433Ii6T8ODcRW+y!^p4Nbyg9nu0H8)<4u+0kSL;r}}xGh&# ziCBubZ{MiRSX2@8kn%j4b)1ZPU|xs{b~yWbP_R#Ut(9SJXQTIVqZFf)!b!I#a}MvC zBQ+wI>zySvz-JHu1F*ijrfC8OJQWZj5tm;A3&J5V=$-RfJvEgd@9#ZTxtOOQ05(J4 zyQ~V8kvk55A8J5?52yu;8w}%bh;`b08R7vD;W_#3Z{Y!T0jR6OTWPB5Wb4=k``R!7 z04(76U_2)BMp)$o>#MD0F5Pz+fDm@rjQXDzO0^-)2!&28gSMm|h}~*a{`fE`LUGp3K2otcEL|gFK%!;ACBY1GtF= zCZFm3+}r6Tn`u(`t2h9Ab_^inC)AYJ1_0KX z!EknU;I2CbD8YMD-nXrc{jUI8L&$Vj(-ByB@CEeZcw+N-kV5miK@RT?7Sd->s4FI% z&>*lt1^{q5`lDxGI=L!C>5JrWERbwH-HaUzG_2k|E%lD(QZ5G42;k_eui=8zN|=cR zfuxa{R29J}I(CI3a{iQ9$damp-9?X^7kJ0CtT{4<0NhBJumG??F;J?a#z!?Wy>c_M zQCTpW{_r8T;35-Zl-Cci=5{ogMpRg9wF?p2Q}LjwO`i| z`#%Z122tb-JZ_0%p6&Kio%%0~tz9Ex5t2!dM84jdSQ@U~WlZ*~|H^jOHKzJcGBrwM zQ{daiaJ|k+YDWDguXOjd8z_}o)~6->b~MhkUn;w`{+p;@_k``g77zEGf-PM4q@$|z z^ZEL%JFVSi1uRBR%Ocwf^WD>d{nCYJ^{hfR41C~4>0%Pm9d-Jinb?aH{>j_|5NpqD z%71L2=&nwfzdE%kdxdnvu7O|AeBnPCfAFkR1-56QQuR))S%a(g*L!yVRHoYIAE%Au4hQol?-cN_4cUsl?;e!2}&yM=#`p+7Up1jMuC*c#A zpuYo)pzm8JQhFnpN$Q-B+O;BnYWVzs9qIv%c*JlQzw}s+5^wh#jkEq60JP#siroi zUtUf5sS=*NoG_I7M<*53e_pAkviE8H2aZ*mR<_x9?~(Ym8~D$ql(;qT20B%Z(L zsx<#pfW35r@;Q;Ko@TuK^G&!a638(Ft(o|&Yz_ zSSA<2EgxGZpTez>U8YdTtyo#6*vPHaQKr<-tvpKn-)`ULIteN|JbAPO%e5nT(6Qy{6ds-I za-BjR-O6&^MjpM6a=m^Y{n2v$X&!^ca)UJw||Lms1xa-)Ad#$*-7G`uEE6(;Pw zrhFBqV!URu6=tfuceN_+8uFT3RG8cHS~yl%c=B5QZ#K{>g%^`ufhpv*uB@;u=D8~0lw(^lG zpMzGVgCXBzi^|8ge2$Klj-Et5r@%_52tMc7O6L?lm+VTHLO$2ZO4mj{xBuk^R=Q8~ zc`R0XtnqnnReB!sd0kX`{p0g~Ue2=s^jTEr`8ndvwCzL2?{~pY`2ygN+!h=k@zdI- z(0B54bUM()1r#Ev#z}*$w}ZAm@-zWi^l^ceRk57vL8Fm2O;rIs{Dp(q;89%Ynp4y( zB-Dx@+DE|b@IU>v?TbSCFjYsEZe#R8Y}M*CGYGmab+%lBhkyW!Of_8}ki*UibJLj( zO)v~bMp}R}|ENd03V6?`2Nhyj*ZC9qa#{VIXvRkpt(}sjw5iIS6H2idD-iX%fInYk z{OPdZD)w0=5zCS}B3SNBc`(dkRYir+2|)7GP-)YZ?=V}v5xnV~+98mm8&BoW&oMrd zW9^i?T>UK22~!P(z7X`U97xC>VL9N>?+4%#Q0bLBzPhLkt?dj|oy?`6@>t(F~}&|sj?sYWLYqUFVgTp(Ep+) z(5<(7$CMi?ud@Z?AOGHKR#A$aWXAUK_9{RAI3f*Rxjztw!|`iY)f%c7_WA ztDu>+8OWM|##-+e1eWyy>fym`t@wH^{)Xl2$*nO;f2V?M%`WThE+K8Y0c=mBFjY0+ z`5tkYxxAWs7|7P8-fitvq7}_j?o8Dc$yy!R8(77U7fSgTiO$`lD0a=L-uvM$>>s$_ zsdeCoMg|eEHpcY<*6!&dgS`pE$)i<Q-Z3h*l!E zSzd^K)U})X*MJ6#_?IFSC>kq&iF$k22MD2R>bq8(RESo4ba8cB$);bPk7gp#nw%hgBeI`Zhoc0ntA_&CDw7UyFDrH|F2r~pBjSh%MC*p6h}RQMw@4~?%5Wi zqx5iWYbWh+c-mr*@`WbPj%UyuVtE?*yY?kMVR-JJnE&*^@u8RJd36Bu0p_QdKS<(C zYugYj4(;+h4|JMmm)M!cowp#aDzRAKmp=NS{leWD3-NzQr@slPU(+=hG?MJMz_&dx z1+fuYjQbnd6tE{w9Bs0B0os?{$ILVZEH|YOG*;}PsQvk&B0wJ<;t_>RlOgu#$Cd-OQK2|_&@qKJ3R1ND>omGKP@-mUnCa^g*=O;8geIz-6T^eLfb@Dyv5$YP z5Ad=H&ErM0jb$D7LcyBhiC{V$~DN$F}PER=zNY8auT|gFDdd4^s{iF zTd}EIih{NXV3aAIG71=$Y7E$FMjbSxU?(D(;v2F)93*43EM8BH3C(MV%>-<0C_$uk z(Bt@&cOT54Q3cXQ^;uUjXrttcu+$48Dt;-e%BX6a}i1jFar0{lA zILOZ*>W6}zu?1}la~vcno_OE%q;&W$(kA_5n$R3^CIUbPb<}$}`(c_IFX$RJ76oQ> zU2%P&?^@f!`zR%%l=ACVI)8rFaZTNO+qxh8&JKrpx{k&V!R%*XgobxeBZx-B={Wtg zhK?K_)NBZGJ2pJ2I~|7Non-HA%id_!J(4ohXb+%kM`K$mTh1m6Wh_}51&U%US0w#6 zTQDz>bZFm%o@PUGX+t#$_+<>>(q}F3$V(p?l+udwZ>41YF7*y6r}hJ5)uzwAC(Ljm z#CjowJ+l3Lc0Wf`MET;8+Z}qpA4(t8gZ>duFjgG_4`uaPjxqHh)=cTADf6pnXuOPPHlKR}M+Looj zgpCT#M2=Thw>1W+bp|YuwFO*^2swCC$=ADG#(EVYjza6r&I0_kI#HV)HpM}x@XMo% zz@XSpPjILAkgw6vA=QWD43SF@G*V$-z*Sl_pr|9DDi8%}61r>;dfn-+!S6A4U|8LW zLCA-Vi9H$%^cuem&pDyHSM{}UBv#ugPPkKLWmF`t!Jnkdgb&+aAn0r~XebC( z9ORLB=`QypnYJT%4e;!;>)Baw|0q%3+bbY;!dpS(+>o`~Pe7eYCWHzh4tdt)6#kQk zcu661uGZU*u=L!DZNrj}1-))FoE!+|{z1X|BR5CEv##4S%EdGKD)l-<1?&-{GpYtIU;Tp7KH98dsIuKMgl)J!holwwoNZ`Rl4er()Y}ynFrH z{3yXSkwpl+HaM#YKnZq%-Xm7U*PeML4tKo+ZkI}1*U9@Fw

    (!sTC4@bnfIxoi3< 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� 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�)(qmJGY<%4C?Rkp9U{5) z3*bH#m)BpMX9}fH< z9Ke~>yLvl+B%GswzP#bbX}}>N6xvSEk-~no0vGr*fpFu%mNVI?OHX^dT@09EmOJM`=t3Emt>r(uVS|Y?X9ZCe6tV;Q28?5fAZSyAxmP`v z;%9&`g|3>%lF8uuME=07R9n&`w4W0`bC~`2u?087I!a_quunY0x7a!D0 z&{c0ooX!Ikcw_u2BaGB07wH4S-_8|50D=vo>;?esc)5x&8BNUSQkuq5V;`P5d(SBc z|L`J=)HWBndg5;hchiV<>H zK0LZVe9}%8+cei5k8He!iF=QN#w)*H5ybfAU1_i-%d^|(&mML{;d|%fI}y)-=1mxH zR*!bi#B24^tW%d-{`GTG&Oo}OEE!=+Ahpez|HC6;WrWewA^6eyuectMUUuYibn911F_Cd1*P8`XZIWais$#o$M_W6EO ztKG6JM}=pNRe)_Mu%rv#QD1tliTN?D7mgI`!RkokBCp>%g04J+x*G%voObRy1O_K-txt&=LE6-h-m81M%k6*n3;b< zie;PPJ$&wbKSKs>O}d#<10%g<#}vSSW8Sns+pLx0&$g*?8~r*6SS0wVLEvZX=E&{E_O^mpMTxus^L}JoYCf zt*3Mn=^zKP28^FJ}qzi~TNlO!V6_3z74N&=OjJ2a>_`xr|l{l%UT3 zMmGcVRD-4Z+Zbkc zW86xA{=IrWG|C~CO)Vg?-$nY8R%cl6JL!k)wr>WPyhafmbo?F9zbbFt%Qt>*DAUc7=tU42Gu+A++mi@t28Y2pe zSN99&E?PUw8zQ-odVF&t7vbNA7GEe{k%G~ zPI0E&!swILmiGnF_-=O7lzWeXNIfl)$01NX-ab7Azo%V8FF1d}zdHcBrQi2sb``(gaS+W>q;d{@=#o434)_1j9kg`{5*V+8FySgZ&cMNo)(`8g~%yH~7 zov%-x2RjoKEw;g{vPAiIq-A)u-TiMI;7=z)6(=z7u#6Uf+jv*(ue@scQoQPMT4hn2 zj$o-y!YXp}>hHdU5`kz+Kz|daetnnqyb>=Y+o+^zarO7kWkLr^s+B$I$6n_mO|WR=*UF z{KfcPS};K*v6RLqN{yKP=yoyrZgi{P1WaV&~j^=erRic|<>}ijjm^5w$_?utn zCt)9crEm=0pbf^fdIuDziTN{;u@#rm?$O(_rcc{aYew~l-x5%!kpxPsN zhrH|MK?P84O$D?x^cta?Ku>=)R^Mv=^N(S~L$9y$xS3lo$rcerzGv#6Hkl`7+!hnr z+)rPQ_9#ZXC9W=lr1@5*9-QMnsu%+srcWWA?KcTSS2BAq1{a&v&Tog%_viZFkW7I< zkB0qjo-T2TW)Zl>vdBpjg}HCWxcdHXK?Y!LGf;3?CAY@FwKFWe%@AW+cdlIsj@ElL9GObS)^uKoJxSk;HAw;T<}&KVQLV7A(k z3HEG>R5%ubTV&%y_Ld}W_w*4Z6{w2pd}p}y$WLI*%DP-cO0h(K1`;IMs+5}|Jg$?)qUnh{^tGL-(+*qzu_Nf`h!Jj#{l3vJx9I{PSc>RbqD|l zeL{tey(|$O4Py3OkIT%(lTQ$0$KNf+TtGOQP?9IJV8`Ae1li!LW4MFl^qtutgPUlJekc*n~1f_zwRA>id zuaG=T7?0{Nqv6(Q6Jk^iKBy&|FYt67gkqi}OVh2hpLO7rG!@_{JL$HZ`LEM~(6D$X zofT7|5)?4L1w5xyFmogbqtT3(NuMVmOZ+wRCcfe3ya+)Vy{t2iDw1*<+tVQe(uBn~ z&~Hr>lpKXN)u%LrD!=B#C&Z>N*x0c6;05B~EXI9STgu`Zx~}Mhvn7Kvu0br#ckV)p z&l;l$dCu&<)wp|Fz!J*8%@}wua+umJ)Cp00mxMXLrS5SZg5x8PJ7hfl%8j4W5y!=^o4LXyqNyiLMgf&RaLu;oDOD921Fyt&eG*0tKDIHz5C2IRnQlYXEhpL3uF&#@QHqcPZ?G|x%y>MQKdXV(O9 zJneV!y3%q>B?TYH(WI8JljN-EoPp7z~4m(x-r#J7I&tJK5Pv7 zSg}I5R)+{+q#dC@6PKGwIfx%7-cuM|yeG0{3Fe4}lnwDGD#-abmYPa{SMapYMPzpQ zE~#SIpe7?M*ros}{agAXo#!8YaL_{987_<+-H#i10pekI!P#-Rl+_1$u}cO10EFIp zL!=qxmE5`zZ$0e9jop(K9wIfsAu<(GPI@fCW>RR*G0klwY7X+Bna}UN`lze zFsrf(-}@Nk3t|MWicUTlU?3cf<44WNGv$jxOt+|aO*&Qf5~eT?-~)%`dNr00KELI7 zF>x93(40eiCM_Q-0%-w)Zh50tUhge#gB*q1c0-=Y(j4HJbRjzmn%i&4v+UadXR_ON zyMpJ_C7h(sGr_*)DdF6&$Y48x5gyJ%nf7gV(emYlf(3bi6MQ}h4Fb^|&cpM8qStYF zK_OK#(MMl=8?c(ePP}vSDyNRdaf^f}3st7w86Xx$*vEtAKHxqM1lxLJ{bXq6@gGwo zB0;u54wn&q?`LPsg;OxO$Xg)H5DZBKT>DM}7P|nc9#-@mT=FQM#ny%*Z#mNe-e)40 zGl>zt<3Qeje*YWLbXo5e3}lhVyY*EblotS3>ryW=;%fyVkK_f&J|X=d`a9%T&@{uV zk}--@LS~xfC66Gb-(j6h1crow@SFkl@%N8R0vF(fI36L!%s%@XzZ%i_ypyR~>=_8o z>EdW0woi95EG0lfLz##ejGcm@@_9iNFMM~k=3c2NM9Wq^u;#9>uR^%a78d(GKex0r{LL`MNAW-cK_Vv zH^&2_L6r;A1~0%a$+YbKb~C0Y8%3K8_7F2x3N5q2G}#E$k0(swClXxZVQtX4Rx%EL zcR-x4xO;3&ULT-lfSF-&Y&N_v1*v6!Evy0LFvwx>R!%44)vcQLAQSQ>x1=wF$X^vJ zJFt#(UEP8~ppU&?aHcdsEDg;~=`>>!f{<4>PFFrR09uL-CRXG^4uzMRGul)DE1#!= zyFT?uBJ%`HX+|QNa8tEu!(@5B=M5Ya$8j0!b_v*jal39rM>|!TnB+$Utg^`rD%0=@PQGm7D@F6cyzwTJf6)Nv3adSfH3Rn4i$F6OJFZ2*s)UAId{ zg0aVs-!!^*RYiNXAa=J`_hPO)3Hd;7rkrp!-TU4WlgPRAv8zniZudTZ40Bq?ay|Zy zYlUjfwP;Ad3nSEa+Y1nG5wMyVDepe6ao%BW6ZO`4WV&&lp?WcAGVM zI^^ofUW}>DiuG;zRRg?&*P!cFT4g!*i9O`V^P0a-@9|D;{=oUb=V{0g-?C$hc|+1rl`=VMx9cHf;N55p*EPHi z$9zRl5K_Y$maA8QAa{0GSjab3| z7G1k&GkYrN9y1=y*REf9|7^t*yefQ*TRLw4MiJg;KlIPh?pa|=u$Wb)rwH_8FJbMOWM(cu7Epomx$Q9F2>a`QB@!-EItjIYAi@6mU*XhdZOAx>ZQNOYh%Rs&zEllHHNl z!v*!}#)I^a-(koa*pQ>&rjAFdVHMJcLnKY}wZx0x5T|aG12T&OABh2grJ}4MH0BkBw^^W?9M*L6W3X zAI5nlEr8un1#m?a{Z|xgsVOweQt%%rU1=Ytma&%1mXmuIJcX)3AOIwatxQB*eTlhUa+r=!WYvuq`7>sd0 zG!%ZHd@I5j+ivOdxqYK+EyI!sA=H^0+5W(eDUqKeMPg@wIo>G{PW*C|X7 zvS&!4=;F;65q~fCtOtUG&8nR4>6P(Mb^bC2RWmaV$1vxhoF0w6xXKrgho5jA56d1q z%7(i$e(U|^V-PIlpz*GFvh%;%_gk*@h9h$T6K#@O6>+SDEMbsHARzg>9?#$pa)?37 zg1S=6B@i7tA9jn_rsLM58)Y;%bjA$56x2l=UfpppC~wL2pE{%|1Vfjei$D&6RJX-G z;dlH6hQ+1jinu3W0T}GXx5^RxUBb*@W^GXPczvht2>oc$hQe|0KEh406-Xk=K#3Ap zcY_JNDxXIV!^5!nijgV;Kb^^)?B2YZt zDGZo^dZ#l?#XyNsCj)nF-0^!2@?|WyF90=40a4d9Tv;_3ybpFXw++))x)Ddc2hWr1 zKtEl@yi|ThIB}{H@`C>7{a(EqpFk~MBL%&CfxPhxT+ji(ow5jTZk?b41c{D&RL6T( zpjuAdT#DT}F=m(~uns(;xk(yk0m`$LNPB;F`Fxay#eING&&jEo>%6cqE(r^^WN^6~@DAQk}tUd_%IDr)I*aP!t1?8$uR)*P2k3~PAAi>Zr=cl>%O=FWy#`5WexcmK**nX}~ zd(Q?^xX5$6jS@t5+AUWi9Hq9&8eRsqPfBw_@2)1Q4b<=X%5n3YUSZl^O{0aiorj}F z%u@bhvrz+n0)?kAqDt4}L(DpM$Gf_%qjkDoD#2YJBW69smLpW)F@_$sF4q80&)-9h z6jV(}L3_A2;f0FuN7oRu>}y4e@IZ7PDRUM|{1m!ZtdtJsk8BJEpb%L~H+K)RNss=w_yofX+|& z&PB(>FGw9A$X}lWsc5(3O)nYkj_4-Tb&7(HZ_&M4@1<6(IY0Y>nhRPKiTaOm)z0|AHUlzJZ&)&#lOp`o5fm z9}MBQb<;_9KKKn%01_~zEc%IuTNR5c4ah>$)3#Sr+pk0uz zX#Of$N}%X7b=d??EO|{mE9NpFv`UGD@03ok4n8B4wL4b5uaT6V0I*(D8dqc<5_r1u zgY7(f=^4Ve91to9ru_^=0rfM<$M4VX|0?&?3@Ds93rJg7Q*Z8&!!sHv0nlI)P2%~p zTVNXB+Iwrp%LeHd2x<1IRbj}7Gyt_c+=~7gs||SiB5w(RxWF?g)lN+!mim}ukcA)Y z=nkn1r-%cTT$jd>_!9S0D?rpq$47V-1J5JAiOCfHpWPtPWF#cxKDT}9`|n4LQknIXjOCyr{A{Oi zdY=6~<_{MdbqNMyeYPj$Vn!&Klcmh^+--p#bDT2`tW6H*XQ~VSAC{W88(rNjm>;<{ z1}6pe3o}tSZIa*@3N!2tk!;ZAAY_$dk$o$-$`fHb-Y?w5Vy((om6tNaVj=zN z8}o|<<6-QU_dA<24#XLAGAsp6PL&C75TxjbWz^k5Dlr0+ekfUU=Zwcsvk_L+n`&c6 zl^ivs2&6=qhIPPpS))u=hCNlJbB+EkGy%d!zO@i8a|9JpM%;Elj^AIqmO}l2_nH(IK32STz zzZp#s_@v|1_6$o9ivlmtfGGT*EBYS*!t2ieYesdSf_+;5?W!exFbW@FH5rF+BU-5t z%i&72QY*lxG2pVIZ!h=5(Zp?y;sZq8EQXcDmswWMz$r_j_06Lxm^UQ7VS;(+u~*fEys$6LaHxU*AF1pYN=*T4e`& z<1`GE%&^Vvi$3y3SYV>9j5XT0f1Az?I}$D$e<-HY`pBQfj=KF-RUU2q&eLt0g*SeJ zU3i(+sRz^lA~DMY8`LuKnq0D(j@(a8Yf%SG`1xU62Rs0Y z2QQ%+*c7kjfXfDj)LoM{`L^j>CP8DWINs`dUKJXy?o#vJ(HoOug1skrGDV4cUCUl zT6QK6q4`TX`8+2j>u6gm{{*80zu^=&XdW;3L*BMCwD(o?T~o6%4SQEs65&5uJ+>W+ zWTKj1-2Kt544Wvr*?(}?zfNWPF%stP+Wb{!S(-37s=Zsy6xJY{Gx=8ZYvY#4FWh-H z3vUN|2WJeUghG+7JvTRkZ-eV3Kdh+g#@rFl)D#2j=K1-r1~UARRq2CAXZZ=uoAh?G z^#$^tvrGF6E=t0uiLITk^Uq;VdxgXE`{>raJ+_0`+gb!ivfQi20NW%U%ucoKfIF;( zzP>9DG+NuEYWKTisrCwur1_y7`c2YWCU%g5xjg($?$3ScxQns-SH$8E({#zt!?+M# z(nY=HAIi0`*FU{YHuKOV|6sA0b`jPyyL)jJbb6qbx#!(%C*52w7vinGc{f<5XUVV& z!Ev4++;}NFzecqhm2Fd16p!u+!9Kra}(AJ>j|`wH9w5`Mh9d zDzGln!7VNgZO9s%)ZcW82}aiKDOdLph|KDHXFqN$JSTbiDLKPsy$&cCIp-l$7%*db z0b#`LT(*{IFW&joAVPyJr3Yl1*2}9nD1SWf-+23p=uN#3uC_acx_0O$YZ?@5Mw1&~ zo?shx-}I;9KsgF(Dx#}m`lUQ765eR1sp=_sE*+}|W49vxTs<|ba|ZnHmhMVRA|Ow! z>yFMhxpWg*3D352buA}j_nzN|{}pXEz+FE%e`&fMm{XsL3(Gb-*33xpaTit!qqOV2raiZmiYm=)C9dkw#E|N~3>^abuew}^e z2R+Az$2WuSG?<0Hu3s&gMG&=?a+t|4Q5DN({v7Wd9>aLg zsB|m>w%!c$e6fd(ocOKd>~$mb1IRb6D^OoNxBe=|;d@I|Y@O|XVZ2>ZM-hO*E$5T< zxY!gSojKlXkM&0Bw_TOV?&|PZ)+ii$d{`J@i{4^p7H?F?Ig%cd`hh1Dqn6}I{&^88 zdl7HEIfwWVZpZMT8$nvH+paj&Ru7%`}e)~uvS)*J$q($HUru7 zzQ5;rGxc!O1>y819ybD`Lue|d8AR+;tZQCW1@2XyAz@{15W?9yDU!>qX6W~~AG@$rXkT&rpr-QO}P-wy?&mX3Wfe55F*mYaFguQE+h`skb+YuZc5q_*8~ z&)i9xwep#;WQigzh~tLgvt%1#0krkG%*WlIiioM?v(#(*pf#%PON4soM_M>No2pC1 z)hVTvCwBELIkxr8BZZit-%qbjKS&zFSwRr>r#6r8f(y5?ThhgeTdQe=ii=CFyofE0F2hiG?Rx2)WElrh>|D4(1W;?FV?`~c!u z2;cY^{}19cEcLEh=HxXd^IXiGFo_{INFG7nOciIEEz^R6^5~1G-0MXYi8WkT^UGm> zdd0Pa3bmXgXlTcJlaVDvM@wKTLdsV`3sr2HrHDIK274xUNBisjlRsOM3d$rNmfR|` zkoG%*P?+2hhvA|~JEm!L62QSW9EP1-Ec^agoj(wN4fSzZ?esoj8`5XUowC^b4N?cpRjuJiQyT@$Y>mBBlzar z8Q!Z>U{zEt)G0Ko{XvxM$Hd3o$x_KfVKVN^S^O>1^+F3uLru# z8w+p9PJU^k>l(yr)zR-id+U9SJo)+@Z7`tuVI&@v7v`f)TWap}bqh^iYPYxDXIF3i zTuH}RO(jyrq<&-BZGbm6WT-Nk;Xsl3uEynnh?|kixm^ald12A-+u=X4(59z+!H36K zGfY-?qcmEDRtbId#ly8pPyKGqC%U!XA=OW^&E%Ia5$O@&OvM4oZ}$!xsRWueD+nO9 zoxC61$qEQiJ(ig$rrYBLh3ZE(WbXQ5fMIOz#xs6HVsJKOYzsu<38UKS3gHH5^t9c; z{-fBJPyQ^k1M~ZkgBN`cs>W!q>X|=la?P8g^N?&I3voUY?H0KvqL1m;4d!vHzB~PLBC_<;5TVdWIIwx3qkys+(0b;@P6+X%PM^V zKRxuWg7|+*6a3lKR;W0TXK2V+Lkr1^2ecJ@YyD@H_Ns_@UW|Zt5$a-N%`g&67y?|#JF0#ZB|K= z8vGM@25HSJMAtW?O?+|Fr%=WC;GF$LX+Mv5>Fm+DE$G1sQkV81ixN2}^1yr3dG$pU z?j4l<4X|NK#Ii3KL9;{rAr$cz=*58`J*6Y!V{}}b@>;qnA&emC#y8OKBPft(Up6{b z^#Yw604!ceiMy<7D#^VUOoo=i6!oq{1;LBXIv=yKNpb$w@XIKlqBtHT85i0;Y&vSv zSM#d&{*#S}lVF=k>VY9#y{vkx^f|uq%|bvxzmR*5DhsA1rA$b=L>3`x{rwv2cv_@C zg1wmP&xqFo+unOPyX_j%akcDy4>?%!PbY)JPByliD(+s0L#-+@K$2lenj@Wj0|OEb zV6KB!2TjWT`*AV--`(F`O|_^DVV(7bY$izuhG>F*yRb!bjxufy+7pm`(*%W+R8$T3OB=sNL8ID6~QLbIpd0B1U3*)UTL2;RWcRKK#xWEj^S^_%W)Mu^ok=izI zU6Yg#pFM{S@dESz%?~L0Z^8oSc;>k>&b$W&1lMQD7}NVVrGew^z~Lyd46+l%X6ovm z2X$bYf;B)KindNMW`W>tu4SCxbC~Fol6L*0k=1OAN)E_@h5Yxcj26m&5AT-9TOvw|GsI1!O63;DT`i%wcx| z0Gyg%^c84wNgN0+=lcdAj0vPJ@${V~-!Orh2^_;x8;Gg_0(}@e{v{Z z0&nD^xWl74kgxm_M;EAsCjlP4=QpEa{pLk1*cSPl)^N>(<1HQpSLL>kc*TDFjQ?#Y z-t9MAmKK;H#7TN6fa6Kpy7$ejXZ6XcR5Xgo$ZtCvG)x(z!| zfn%5R$}R5PL;Y6-&~eatEda_hylyEij zfofvF8Hs)i+#z|AAD=SEvQMN-?5guB;iZCM9?*&!KftGd={!EU>@D1t+7e}1$3cx z7K>W=GIJ#Cd7bq%=$7gi>B9dYduq~jA_PKjKfO>t9 zcOB{{_V*Pi7yh(Xj#Ds_jS+Fu53pY!)ZFnnX}gIt1kyvyd!Aq~e!Ia+^>Iowau7yZ zEpVSOAi0|gMfpU(qxiyPH|U%?`T)lzUshTCXnXJ`jwWb5%N5apv+^;j2m?Uh)~C@^C`&;jJt`? zc0pdccY%)6&$fvE%g%oBlj>HI%uMhg=X1q1Ocy#R(=D!61dlyo$3bhl*sy$GIa5aB zNG>L`+>KyWFNpnv(G9~dzn=+Tswi8_*xW_fc=l639NmMOU6azo!c5aWa~FupJZ-@Z z*fct*i80x+Q_jz*7HRk2dnwxWgP&fm#h_JxowD>Z!1 z9(=vU`s5nJxBGV3r0qbYzA!`czzC5db%#juu}VyQ6epY(zy~Fz3w=mXsXsM%i8j5# z7}m0rUC__pAj@B4%b5n=vbIyL345Ssd$wBrG8hZp`B>INtfDVC??&WdR%V!(bRepR zq#`3BT~D$-VPqQV1Qj08&`A}RBlFNOeC4?oGHL%3V0SfGumy~_wwBC zq-#CwHl!qZn9og2VhuxeoW&7IE(dA0$|3ag`t8-tI5~6OuVD}=3f>|t;!Xk4x8|uEj!P(FdjZg+wAwBZwLHGT-*DT z>h#y(1V!lIeYz&4HpL*d$vnqb4mUaJ4GTnidVTf=vnr&Zg?lmm4DbR5AF|u`41`iK zMfF`oihTNaA%y3R<}N60vX+j_lS9t$@~&a^RDr)aKLWm@Ao_N@ZW9_A{eszwfQ#`9 zo^5@-{~KO;G(nH{^yq%a3e*8V%0RAR0{oS`gGN7&!2n!(m(dN%o1TFSGTOCVd3&br zqPh=UAUYlok3`}-L~iHIbqnDwA?@}K2u#(QZzA&bP^#$KzTbWyd!aE)5 zbgy@#@^n{cB0~UC7p`IKADfixk~Z-`ZR_nGm}e`{wcO}yaB6+PUG18CpNDW&Z*{)w zpLR>2FkA1&Rqw{VQ>kPWlaKhLailH1%MV@jU5{l=eO$fh)!EKsKqzQ4ue(uqA-BAK zMviM@PxCuWGx;%OXx~jpXn4{FdvI5hBCM4D3U*~YVN;*vUHzb)X2p>EN*c#ya!aDe zZEHFkBe`rX`~-4`;o&chPO{0Lu>?Zq*%;^*26*_qy0(=%05_G-`6PX{ywt|ueOoR*hbaRBM;5e^!;n~Q;f=XB~2`=?Lhg_62+KJpGDgNz|mvUQ( zagY;>Tg8IE$Nl=V3s0e0U&hRy=VWI+C4^-krkOF_NzIpwNUhh)bX%uK#T%Q7h1Ukh zhw&hUip|wxtr%E6X+yGiv|cRg!soHtkm2_7;eHy834u6yI=}%B)tcSuZ~nR-hiy7q z98u7uehq&MlqDJz2$5mK>w(76QF#{$;XO@>_1Ht;pcpm7zns^2lH}4x_~?3fk|NQz z)@Kza2eEOs%crv{wk-gKZg263q5WlO1;AmG*f{FMD|Ds*ScP(@E9%|U>xycJmn3Yg z?V5XSXeXjl7s2ZfLYH8)UITSl=y%pC=>^Pk3&A`SM8|a*+w_F|H_DY(4R&*NPU`et*10Eo_@xI3Fk!OEC{@NRd0Vzi@hgkpP<}3k2 z<>BMGXLiuXBzaWt9qJnFI_^_X3v6FMS=`hJcxJ@f_{LE~q2UD?I2(nQeq&8mlSGl{ z5oI*}?Q1Vo6Qh%vi#5MIUCD;xgzgMRJlVt(UwOvc(j!U}ep5(Gm!TA@vm1%E9S^$okG*)N6%%9{d;7M1%J@-P}p3X!5HPf!`7g3_-huf4Tf>3mwjUZ&C z7f!2FaeLffgO=9&94n`7mc-IxC3e}Dg@2Rcg4zbpb!(gDn9}`yQVDFH>mYyddQ~|F zP}SMHHkmR}4VOHQ6pc4Npp_c3t#!a7&F4h(RA;sB3apPgckohdTJ<0sb7>;>VA-5A zx7Jn3I5!H&hS|Q<=uA2x6HHEWM5iL;TJfQ75Z{-nXuX^#z(W#}-pB7mtXJL|ABi(m zTlhPS8bnrx9o3FhHF+l>r#&EHML>!CXG}Ex@&e=>O&cDaQ{gb_rF{v{W|JB({q>8s z;5f@MmV>;<3BejCBYs#C zd;U}&DaM2%(o3!5Lfo~xn;bkRXYjvUkru;EknNQQ8n5_dcl~1eFrk(%e$w?IrRqJl zRqQQiaC%-7Kg+3E)zcWK`h5(6aELY_!|E&23gB`Yu7EX6p%IDc{>SY%% zu++C9=pA!zR-i#vzF7rVb@s{CuDIjG=z}jJi&WpmSL$KCCHJG0n-T9vwdYIq4gE6L z!0X5)MkS+a*V%-;CN+0IL&{s^^Lfa{7#zJ4Com0{wd2`1glLa;NSM4v0kblRQr16R z4qVDF`9Ck=bJX+uY3I}DzglUwVOKMz%y*OCuwh4sABQ0tGb}%Hw2lgJ>>bEcegBrpV{sD z@^h+|>F?M(7*u5=ecR8nMBFEOjJ?WU>QGdXCKV(5!U;F~BaZ3LQ%9JJlgnjITAj2i zTa7ZtMpX|mjgw>nc#R%nQsSV|4 z0r}yki}Nh;mQ0C38S4VJj`rc#Mtt~dIJL+ppNNA?1pyOjGo>O>PrH6LFYpWjosy|k?G4ktUG?$qXO7ZrIV0DYbe)Lsn4jI zazUsVzk#y2(y_;2)o?TCm8KKI4NJ^Lp@iA|Ns^^22Th{Ln)^eZfCD-8sr7R=CEz+J z{OwGf_)-mBAhfIgOjC@Y%0x=J2E4nSFoT#v@?g&{(35r;&G(HlgO#qLyZ$}=cp}zH zMm?HnP>^Twwwkm9Zkp2lg|IIUs>)gQgp3;X} zY!;I8fFjHK?8k6?w{gKcV6%+1ZQTN1k9OxWZMos3h@^@yp96>=aNb>OQ72zI6Z@A5bt%~J7nUxkUv(H z)Qhp<;H)a69gD2JzW;GQ%3h0_P!CR%dJPJJZtmX#Jpwez2^4~Fj_jNLA_kxig@QY+ zH!{Wk$muibH6xu;VenqgB)c8Lh!D^2IL>8d8v_XoJvDTzf@=Mui5&!uQ18%3Qv|2& zerQPkYlC&bqn`N5ILpF%%FmZRZpgX2TRrtEwo8(nR$wDoq!9(2jOttr?LYq>MmJFT z*GEFBDpRTJnz;r;5oUCvy)RKnF1(ie;m>qTAlYE-`to?krD)+ zdjGKbQbJ3=h5|cMp9l8cn6`vnUVVDgW!5!l;hx>kH75`?d8nj}{#gII^EPBPH%E2Z zjr$vFbG!tzYpKm+G8OAAY8u_-lRGf$8j&s%Layn}r?KMOC?n%vMpy#U_>=4gGao6T zwA>_=;czUZWIm>`%9c*x^&R$+$gTG_*bl~4gFMM@C7QE`>j|cya$=(Rx$<-wcThX@ z7(sRXYxeTJyRtVHF1sxU$9m{fiff(@4p4EDyk^cXzx_}K&8c(@3%8~B^+jd_A=M)U zka<;Q@hw=M0-cj_PFie?VR#E{*?hFrKMF8tG7JL-Z=0^|Dri8ey$Bt19?g@uZPgI( zyt@v!^vc&HjSLYVRLF#Yx0TgqCPJ^a2pt% zuX00xNsvrN)s^8QEB1VtdJdt^OSBN8lb7$Z=Ege0^!^8dkG69W<_3N(c6vXuVYI9p zC4tb=2>#O>-z7#LxI0)r%5eA&I+jloQpz2{0?jRcJ@gwn-6d<>p@Hz-E(PHHG@#fz zhQO2uf+#uunsR-{1fp&ALeaMDfMxsr!$_u$u{8X)2ZCYQFow%dvOdxf#6_)^TfJGmTkLIi&RD54n2~!a_}N zn8S_r{Qk}oM|r(D*7za>T6W=U1*asT+dPQoys5IxF312hg39b4*9gg5tv7P8l93r-qf$ndXRtz9v9ligGUet8SLJ_I=; zB%h`RB%4&<;bF!Pv%qe_C!z0cN;>5xYdWp&-Xf-AU1v`a!X2}BriS(@9`GVvei{e3 zx|C?ysYPN)siSyTs|eob2TF`ltqBIqVv)?32tB#wFo62?;aar#P6m)`WnrE%u2f5sJRK;I7w){ zLO^0UW||t!4{m}`5lSIdF3aKc$%EAdxaYS@(R7(TW~*^D%zQ&FTF&zz+<@1uggY(H zMb^7VV|=7YLs@n?anI=M6WV$BXXw?7%cnayowwoit=t78DW4X>S_Iwg_^;{<;hy81 z^p3Q)bB0zweTC>e1k}YBz0YbQ<3lE>RsVw~!ki%RxIS~FM!@OmZrtJa^2@1)o$Taz zo?My799wGZP)`eU+d&9g8NK9|6P=)6o2jw|6C8cfTVG~-Cf)nT^9C<_*&|n0lT2Baz4mXwxPHF zY5K(Fxbjl*d-FM!EJIvBEf+jXl^1<$qu@GySi^t{fLQcXT_F28uF12P=QhfBacZhY^tI7JJS+@`-Q7bmEKdm9?ai3F` z9PdEOOeLj=eaSJ3lBbwJn|aEU+?PWC|@D-FaZ0V2i!m zJx-_;x`h5SR2lJ#@vIp~&lB-vVrCBJEm1GM@XrE4&mdxqsK|F{so_dCzc%Gv?92lY zX@W2^{NbKV?hbusKhoWQMgkU%x~h9%HGQ&Sb$v;5l4B$%vg*xlr(0h0%~Zrdtu*@G zv#Nv^i>C~l#N^AR(+A3ElS{DNY3`75q9&BhVB#w3)2syoo#c5}@WwaV{H8_DnR-hX z&Hb9*_6}Kx_sPiIvfKPuCbR$2^fpWG{-6gdrdF$BD>lGGAcBt=S%0@$KxB{BV^LC@ z(~eCsf}Lj71LVU_0mAx~`b()zuMYzJvme}Y;<1?`@aWz3MigRR`;u5wf#qMZ_NGLX z5@H2v-de3L0dK(+nsmjw)g26qi79$#>6LCCt4{OQ85OMODzhl{pwLH&c)%@UOFBMI zAo_Og3(6EW1F*L|b9n?So6sC_GN^JL+zf72EjBu?vMx~QPFjc@6u-JF zeDPyu=f}Ur#o%}7Ru1PzoZqm&0VHhcA#ZPoR{eyC5wbzy-0oY>rdTcaJ#TzQ?2;J$ zMT|5Hi;t5}UDzvtc&U<2UvQm2*%vgB`_CX&5oY(|^gxmd$jt#_#|9ljY#**{J&Il0 z$}3=poalrXYBvw4PTTl4FFak$DJBN`mS>g?SM@px;~g8HS!#}5Z-wp39zBXiEF*ie zL4(jVBqpufISbPPt!7FwW%O@)kz7y=9yx|`Yi%|6bX_a&`^EHpE~)_EwH+f_5xL+LLy@yw+2Hl=pb6$O>H^cGML6ttao~1J!WtS(mz+_%O?- zFc0UmT~o==eLMBTnrL??)NJyore1b@R=~#(zhwz8a&ADXhK`ko>E$ebHK2f?>I|i0 z$W}cKwl0-73pnI}}A{=~uU`O=BW8Z!! zUp(~=co2y~B{Kq1!N5;{5{?J5Xhv`UautQgU6oYC+FAlPX!F6sPyk_YaonIYFZEi= zq{>tACV^>mW=%1kQ1u^k!e*)?dfTXptuKu&80m_)aC%6`^rIj<{j^y9D(Fycao}^c zhcET6cGJ=?D6khU_4I=>(9ocRQSF2(s2Z7GCJa(HnWbYaY^+Q}sww;SpS0NUevBju zhUjZ4|FhrTZ@ukN7m7H2JhOL3C=qL}kRvH8vDCYW>)&o2R9_sGg?zgHiOze2aaik) znz||>c6?7PW;hS6qOF*SsX90IISJ#bqR-joOt)?EIx8qJkZ7%R2l^$k%LQ8gPX(OV z_5Jz`bMv;Yx1L7)R_+74sil|t0O~b>mdixEmi$X59&4a~oJ*Pe7fCxoMZLdfm%64^ z7hAF35y6C`O65iUfR^ARH5P1=HkY%|Be%cqg%7*qSqc%sz2^|+VSb1;tIsp*Cru^@ z!<65zE2TQdtBqsVP6+$DjYmuVrSYBxJ!JSO9eNWlM~im13@$D0%HzH5qfQii45e(} zi~ifwaIn%!6OeZ7H+cH;jeB6=39#u;b*4}$8jTU8^sF1+Uzw;loN~std!&PAIP^!Q zL5Ut0eJO9Ns%5;f)U1=jU(ukKjgWD7TPiTAHJTkCqjCiMbnTFR+r;%fkXXDuk1dV& zp&7RtcFJ31gB=bT+?jWKYEsNKdjQgr9_Hg)zEBC$43{%FW&OKd@GzyO-NN!2(# zHCUEAF*V*fQ&_hip3OlhMtb&@@r)(z!&2*x5B=fvtS_|ij;^Mi^6UNX+0=vTEuTm7 zRVbB79bZF#@AVBsMa51fp?8rRIo!c5JdsOZ7qf*B_W#ue5g-J~CiN}?j<}YrlbjT6 zhg^*N$GG<4lRma{s_uDxh@pK{lyOVWZ(+fTFyLs{L@Cej;<8uJ!uxZW>=GTj_jowu z$gbLRr1Bod##@Y_=%D?NM%{qIPNJ=)U~n&j;JEps+|c)%&azI!Hv7r_A zeB@`dzxTOMx%1%QYz9oQ5&ySzhviIuw(#UZxeK@K04+QR(NiN z>XECrdIp^-5xd!l7B2}fJ+R0YERHoG7qF=p2b`MV3IgDfI93h}vbARnN?zsP4=?q( zfB5caVdFDxvcEccMbdmwH_!OFQ#VqpB6K3+gFMp>@%vDlwcOxBX>_`ZOo`1Jnep&z zjnX20O665>uIaPYE497qnGE|N8YKWS6!ms1cl`j9im<4|vH+ZDAgK?hmQRQerM zFP$y~PqrUEun*2zb)M4z%l-aSn(s2G)wMsxQICZMSu26PPt zn^kt{vSwh6N^gU}9pxBG`AZ{5D-*e|`9dY!AR07pd{RvbSsfPorIimDs(P=_9Ka={ zsrQ^l(WUbLvT^+E_ZZrjmuzS}SIEQAur}@!c#`rVdn^YA$-wvs9^7AQur?T9=jcbd zif#}=m}yo@6sj zftOAzZVYBv*&8}en$w1_;^cI&cbcmD6y(7GS*G3(8lpB9^d$ASBpCU1Ae@x-9q*=9gK3=*0o&sLj4eR!^-IvPl z+42xvQnuzxjE%oPOj$wh#~OU-Te%+y7_`}y zD`?k7*8GHSuSC+N4=EnU12lYz2&&jC$P1s3c}0>D7%Az_6*iILP&`8|6@B?X}vF} z_QHb-QvGWJqV)eipOb%F2$AoAdF(nnA~8t4)irM>WS|l>_jrm2HSy-X?Xs)F&NKM8 z0a@+yloh!cqs+<`3iMuwgs>N3s+Zb0t;0>pAj!ng8wVLFfL;)_gzl-c&7{hJX2M$s z4_a~2(QZnUmT({n++z^RMI(kC)BlPYw(d($JLHu#-VGE-?DO5@2fdl(;GP*1^_Qax zU`TG~1OGIg+ERTxg~n_Socu6_!?BXi%NS_zB7JZN4z>c@#d=!vGbeM8)OW z;0tW#8rE-sZbB5)1#cttW?w$CVehTNZ*-X-H~yg~$G&OvDtgM)s^` zIp#DrU};K5V)7?&mP1A0tiic&fgyWZyJseYE(E+_>9P{qTPkRuXMfvYEHMFt{h189 z2K2o@r)BY)M6?e*h*ZHM1%tyr_S4D9i5e5Z%&glyXhQ?oCv`q)Wv2#wnTlr5y)+`4 zBVjYTLw0SaAkaeNnfUp$h~w4ISm<`Kf%;K>Uf#XnfoB7nDP-pf{hyoCkQN@4hBND?Plu{ZnYadW3JR%+MI1uK+I?Oue0`lShE6Xmk=70aF-Tw69!lF@1iuFib>lBhzA&Zd1_I>I3JfdCl37X_nuSzQ zOb7@F?8Lf47)hWaQvISr>Fl*NPm*IkXCor|VEk$wg{5-fKJOy+c}dUm1$XZ8LGC~g z4ZPi8*G{iPMeZiuciSx>0!XS^6~=k|&4}h+)oc-itVec9MsIf80%$%J zER?;z&qoke_~BP}F4Td3tj!70YZMq72&mmIW*FD?J$R>1eZZ4&_vUN--tX6=@FBCi zNlpkPUPW1goiLQ|#<%Za@BvT-+i%w1Co>6fcdXTHPKI*lhFC|*RCJMGSx7R$zsLuR zR+d*JyAHX87JMipq5NxvkCyta=>AOChl$7{G*XP)d+qH6DMV;L-i|CbUV%?!NFSuh z#h-)iT06WbpM>+m^oq|atTtRWYvCTp)1@qQt1PwCQ{whW*i*gQQ%JS+&y$8fR}NoG z>gg>XFOx?*FK%8`)&q76&T2=ZV(HWbn;zqq14Hy3PR%r~eLj2#<;Kwx@KVgN7-U|g zRS>H{3l+SLa_zKw`faE{(uXUm%&LbiAshBRMD23!aP<;O)Qb;c-j^{84FMi>D05Nm z*z($}eJrrrG_rbx-MrWhlWbzX9`E-1q{9L_6#N=2iTkMydJp2LcIBF%0K70yCWDF~ zTiHsGgZTZS12zLg5IK_@@X5Ar&^PGAnk4u?$!>d;{KAunj1XeXccBc2(1bjwkWa{% z15HH4$J2_{(DGMWM7@NNqJ=5F@nFA>96Aqz5h!>d5e#ZtcQ$PPwyaM?f(t!sQyg_l zp^NmrXExyMB&95QnpVh_{-Z`S%-q1P{&5EK4ym@3^_m>;S=8?SP2BVlT!{G3YBQ4& z`ETC0nGKi*hNuY6zM<${Zq#TSPnmPHwFdw#ZK|P8F`x#gDmgWb7jUNvTJ#u(NOV9@1_p6sh{XXiv z$4P0kMpMgXqIR$&qYrN9)@=UTEqe_jzI5DWz%FY2T>t67kPw0CJREb&qCA2Sde*tc zt*YqB6a4KO#Mg3nQOp14_13HUvP)y42qGw+2jTzWA$R-g_h<}G`7=Qs2oCt8D696O JRK_gue*uKEw#)zk literal 0 HcmV?d00001 diff --git a/images/range-begin-end.svg b/images/range-begin-end.svg new file mode 100644 index 000000000..8e2b2fb6c --- /dev/null +++ b/images/range-begin-end.svg @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Past-the-last element + + + + begin + + + + end + + + + + diff --git a/images/range-rbegin-rend.svg b/images/range-rbegin-rend.svg new file mode 100644 index 000000000..dc6045fcf --- /dev/null +++ b/images/range-rbegin-rend.svg @@ -0,0 +1,1232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Past-the-last element + + + + begin + + + + end + + + + + + + + + + + + + + + + + + + + + + + + + Reversed sequence + + Reverse past-the-last element + + + + + + + + rend + + + + rbegin + + + Reverse iterator stores an iterator to the nextelement than the one it actually refers to + + + + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 000000000..13c962809 --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + JSON for Modern C++ - JSON for Modern C++

    JSON for Modern C++


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/integration/cmake/index.html b/integration/cmake/index.html new file mode 100644 index 000000000..19b1ec9ae --- /dev/null +++ b/integration/cmake/index.html @@ -0,0 +1,49 @@ + CMake - JSON for Modern C++

    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 to point to the appropriate include directories and INTERFACE_COMPILE_FEATURES for the necessary C++11 flags.

    External

    To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration:

    Example

    CMakeLists.txt
    cmake_minimum_required(VERSION 3.1)
    +project(ExampleProject LANGUAGES CXX)
    +
    +find_package(nlohmann_json 3.11.2 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.1)
    +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.11.2 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 can be used to automatically download a release as a dependency at configure type.

    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.11.2/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.11.2
    +)
    +

    However, the repository https://github.com/nlohmann/json download size is quite large. You might want to depend on a smaller repository. For instance, you might want to replace the URL in the example by https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent.

    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_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_MultipleHeaders

    Use non-amalgamated version of the library. This option is OFF by default.

    JSON_SystemInclude

    Treat the library headers like system headers (i.e., adding SYSTEM to the target_include_directories call) to checks for this library by tools like Clang-Tidy. This option is OFF by default.

    JSON_Valgrind

    Execute test suite with Valgrind. This option is OFF by default. Depends on JSON_BuildTests.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/integration/conan/CMakeLists.txt b/integration/conan/CMakeLists.txt new file mode 100644 index 000000000..fd3e9ca71 --- /dev/null +++ b/integration/conan/CMakeLists.txt @@ -0,0 +1,9 @@ +project(json_example) +cmake_minimum_required(VERSION 2.8.12) +add_definitions("-std=c++11") + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup() + +add_executable(json_example example.cpp) +target_link_libraries(json_example ${CONAN_LIBS}) diff --git a/integration/conan/Conanfile.txt b/integration/conan/Conanfile.txt new file mode 100644 index 000000000..a8a3e7037 --- /dev/null +++ b/integration/conan/Conanfile.txt @@ -0,0 +1,5 @@ +[requires] +nlohmann_json/3.7.3 + +[generators] +cmake diff --git a/integration/conan/example.cpp b/integration/conan/example.cpp new file mode 100644 index 000000000..e5a31be4b --- /dev/null +++ b/integration/conan/example.cpp @@ -0,0 +1,9 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << json::meta() << std::endl; +} diff --git a/integration/example.cpp b/integration/example.cpp new file mode 100644 index 000000000..1a7ac4de2 --- /dev/null +++ b/integration/example.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << std::setw(4) << json::meta() << std::endl; +} diff --git a/integration/index.html b/integration/index.html new file mode 100644 index 000000000..5bef7588d --- /dev/null +++ b/integration/index.html @@ -0,0 +1,5 @@ + Header only - JSON for Modern C++

    Header only

    json.hpp is the single required file in single_include/nlohmann or released here. You need to add

    #include <nlohmann/json.hpp>
    +
    +// 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.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/integration/migration_guide/index.html b/integration/migration_guide/index.html new file mode 100644 index 000000000..798d44324 --- /dev/null +++ b/integration/migration_guide/index.html @@ -0,0 +1,57 @@ + Migration Guide - JSON for Modern C++

    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 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&) 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, accept, sax_parse, from_cbor, from_msgpack, from_ubjson, and from_bson 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== and operator!= is deprecated since 3.11.2. To compare a json_pointer p with a string s, convert s to a json_pointer first and use json_pointer::operator== or json_pointer::operator!=.

      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) is deprecated since 3.11.0. Use json_pointer::to_string 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 is deprecated since 3.11.0. The string type can now be directly provided.

      using my_json = nlohmann::basic_json<std::map, std::vector, my_string_type>;
      +nlohmann::json_pointer<my_json> ptr("/foo/bar/1");
      +
      nlohmann::json_pointer<my_string_type> ptr("/foo/bar/1");
      +

      Thereby, nlohmann::my_json::json_pointer is an alias for nlohmann::json_pointer<my_string_type> 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 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&) 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 to 1.

      #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1
      +#include <nlohmann/json.hpp>
      +
      #include <nlohmann/json.hpp>
      +

    Replace implicit conversions

    Implicit conversions via operator ValueType 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, get_to, get_ref, or get_ptr.

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

    You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get.

    Import namespace literals for UDLs

    The user-defined string literals operator""_json and operator""_json_pointer 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 to 0 and bring the string literals into scope where needed.

    Do not hard-code the complete library namespace

    The nlohmann namespace 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 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 announcement. Do not rely on any function or type in the details namespace.


    Last update: March 8, 2023
    \ No newline at end of file diff --git a/integration/package_managers/index.html b/integration/package_managers/index.html new file mode 100644 index 000000000..5f4282e5f --- /dev/null +++ b/integration/package_managers/index.html @@ -0,0 +1,96 @@ + Package Managers - JSON for Modern C++

    Package Managers

    Throughout this page, we will describe how to compile the example file example.cpp below.

    #include <nlohmann/json.hpp>
    +#include <iostream>
    +#include <iomanip>
    +
    +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.1.0"
    +    },
    +    "copyright": "(C) 2013-2022 Niels Lohmann",
    +    "name": "JSON for Modern C++",
    +    "platform": "apple",
    +    "url": "https://github.com/nlohmann/json",
    +    "version": {
    +        "major": 3,
    +        "minor": 11,
    +        "patch": 2,
    +        "string": "3.11.2"
    +    }
    +}
    +

    Homebrew

    If you are using OS X and Homebrew, just type

    brew install nlohmann-json
    +

    and you're set. If you want the bleeding edge rather than the latest release, use

    brew install nlohmann-json --HEAD
    +

    instead. See nlohmann-json for more information.

    Example
    1. Create the following file:

      example.cpp
      #include <nlohmann/json.hpp>
      +#include <iostream>
      +#include <iomanip>
      +
      +using json = nlohmann::json;
      +
      +int main()
      +{
      +    std::cout << std::setw(4) << json::meta() << std::endl;
      +}
      +
    2. Install the package

      brew install nlohmann-json
      +
    3. Determine the include path, which defaults to /usr/local/Cellar/nlohmann-json/$version/include, where $version is the version of the library, e.g. 3.7.3. The path of the library can be determined with

      brew list nlohmann-json
      +
    4. Compile the code. For instance, the code can be compiled using Clang with

      clang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std=c++11 -o example
      +

    The formula is updated automatically.

    Meson

    If you are using the Meson Build System, add this source tree as a meson subproject. You may also use the include.zip published in this project's Releases to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from Meson WrapDB, or simply 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, simply have your build system require the nlohmann_json pkg-config dependency. In Meson, it is preferred to use the dependency() object with a subproject fallback, rather than using the subproject directly.

    Bazel

    This repository provides a Bazel WORKSPACE.bazel and a corresponding BUILD.bazel file. Therefore, this repository can be referenced by workspace rules such as http_archive, git_repository, or local_repository from other Bazel workspaces. To use the library you only need to depend on the target @nlohmann_json//:json (e.g. via deps attribute).

    Conan

    If you are using Conan 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. Please file issues here if you experience problems with the packages.

    Example
    1. Create the following files:

      Conanfile.txt
      [requires]
      +nlohmann_json/3.7.3
      +
      +[generators]
      +cmake
      +
      CMakeLists.txt
      project(json_example)
      +cmake_minimum_required(VERSION 2.8.12)
      +add_definitions("-std=c++11")
      +
      +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
      +conan_basic_setup()
      +
      +add_executable(json_example example.cpp)
      +target_link_libraries(json_example ${CONAN_LIBS})
      +
      example.cpp
      #include <nlohmann/json.hpp>
      +#include <iostream>
      +
      +using json = nlohmann::json;
      +
      +int main()
      +{
      +    std::cout << json::meta() << std::endl;
      +}
      +
    2. Build:

      mkdir build
      +cd build
      +conan install ..
      +cmake ..
      +cmake --build .
      +

    The package is updated automatically.

    Spack

    If you are using Spack to manage your dependencies, you can use the nlohmann-json package. Please see the spack project for any issues regarding the packaging.

    Hunter

    If you are using hunter on your project for external dependencies, then you can use the nlohmann_json package. Please see the hunter project for any issues regarding the packaging.

    Buckaroo

    If you are using Buckaroo, you can install this library's module with buckaroo add github.com/buckaroo-pm/nlohmann-json. Please file issues here. There is a demo repo here.

    vcpkg

    If you are using vcpkg on your project for external dependencies, then you can install the nlohmann-json package 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
      project(json_example)
      +cmake_minimum_required(VERSION 2.8.12)
      +
      +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 <nlohmann/json.hpp>
      +#include <iostream>
      +
      +using json = nlohmann::json;
      +
      +int main()
      +{
      +    std::cout << json::meta() << std::endl;
      +}
      +
    2. Install package:

      vcpkg install nlohmann-json
      +
    3. Build:

      mkdir build
      +cd build
      +cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
      +cmake --build .
      +

    Note you need to adjust /path/to/vcpkg/scripts/buildsystems/vcpkg.cmake to your system.

    cget

    If you are using cget, you can install the latest development version with cget install nlohmann/json. A specific version can be installed with cget install nlohmann/json@v3.1.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).

    cget reads directly from the GitHub repository and is always up-to-date.

    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.

    NuGet

    If you are using NuGet, you can use the package nlohmann.json. Please check this extensive description on how to use the package. Please file issues here.

    Conda

    If you are using conda, you can use the package nlohmann_json from conda-forge executing conda install -c conda-forge nlohmann_json. Please file issues here.

    MSYS2

    If you are using MSYS2, you can use the mingw-w64-nlohmann-json package, just type pacman -S mingw-w64-i686-nlohmann-json or pacman -S mingw-w64-x86_64-nlohmann-json for installation. Please file issues here if you experience problems with the packages.

    The package is updated automatically.

    MacPorts

    If you are using MacPorts, execute sudo port install nlohmann-json to install the nlohmann-json package.

    The package is updated automatically.

    build2

    If you are using build2, you can use the nlohmann-json package from the public repository http://cppget.org or directly from the package's sources repository. In your project's manifest file, just add depends: nlohmann-json (probably with some version constraints). If you are not familiar with using dependencies in build2, please read this introduction. Please file issues here if you experience problems with the packages.

    The package is updated automatically.

    wsjcpp

    If you are using wsjcpp, you can use the command wsjcpp install "https://github.com/nlohmann/json:develop" to get the latest version. Note you can change the branch ":develop" to an existing tag or another branch.

    wsjcpp reads directly from the GitHub repository and is always up-to-date.

    CPM.cmake

    If you are using CPM.cmake, you can check this example. After adding CPM script to your project, implement the following snippet to your CMake:

    CPMAddPackage(
    +    NAME nlohmann_json
    +    GITHUB_REPOSITORY nlohmann/json
    +    VERSION 3.9.1)
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/integration/pkg-config/index.html b/integration/pkg-config/index.html new file mode 100644 index 000000000..720f0274e --- /dev/null +++ b/integration/pkg-config/index.html @@ -0,0 +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)
    +

    Last update: March 8, 2023
    \ No newline at end of file diff --git a/integration/vcpkg/CMakeLists.txt b/integration/vcpkg/CMakeLists.txt new file mode 100644 index 000000000..d31f4e835 --- /dev/null +++ b/integration/vcpkg/CMakeLists.txt @@ -0,0 +1,7 @@ +project(json_example) +cmake_minimum_required(VERSION 2.8.12) + +find_package(nlohmann_json CONFIG REQUIRED) + +add_executable(json_example example.cpp) +target_link_libraries(json_example PRIVATE nlohmann_json::nlohmann_json) diff --git a/integration/vcpkg/example.cpp b/integration/vcpkg/example.cpp new file mode 100644 index 000000000..e5a31be4b --- /dev/null +++ b/integration/vcpkg/example.cpp @@ -0,0 +1,9 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + std::cout << json::meta() << std::endl; +} diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 000000000..64dcbc926 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-\\.]"},"docs":[{"location":"","text":"JSON for Modern C++ \u00b6","title":"JSON for Modern C++"},{"location":"#json-for-modern-c","text":"","title":"JSON for Modern C++"},{"location":"api/json/","text":"nlohmann:: json \u00b6 using json = basic_json <> ; This type is the default specialization of the basic_json class which uses the standard template types. Examples \u00b6 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 \u00b6 Since version 1.0.0.","title":"json"},{"location":"api/json/#nlohmannjson","text":"using json = basic_json <> ; This type is the default specialization of the basic_json class which uses the standard template types.","title":"nlohmann::json"},{"location":"api/json/#examples","text":"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 }","title":"Examples"},{"location":"api/json/#version-history","text":"Since version 1.0.0.","title":"Version history"},{"location":"api/operator_gtgt/","text":"nlohmann:: operator>>(basic_json) \u00b6 std :: istream & operator >> ( std :: istream & i , basic_json & j ); Deserializes an input stream to a JSON value. Parameters \u00b6 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 \u00b6 the stream i Exceptions \u00b6 Throws parse_error.101 in case of an unexpected token. Throws parse_error.102 if to_unicode fails or surrogate error. Throws parse_error.103 if to_unicode fails. Complexity \u00b6 Linear in the length of the input. The parser is a predictive LL(1) parser. Notes \u00b6 A UTF-8 byte order mark is silently ignored. 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 \u00b6 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 \u00b6 accept - check if the input is valid JSON parse - deserialize from a compatible input Version history \u00b6 Added in version 1.0.0. Deprecated in version 3.0.0.","title":"operator>>(basic_json)"},{"location":"api/operator_gtgt/#nlohmannoperatorbasic_json","text":"std :: istream & operator >> ( std :: istream & i , basic_json & j ); Deserializes an input stream to a JSON value.","title":"nlohmann::operator>>(basic_json)"},{"location":"api/operator_gtgt/#parameters","text":"i (in, out) input stream to read a serialized JSON value from j (in, out) JSON value to write the deserialized input to","title":"Parameters"},{"location":"api/operator_gtgt/#return-value","text":"the stream i","title":"Return value"},{"location":"api/operator_gtgt/#exceptions","text":"Throws parse_error.101 in case of an unexpected token. Throws parse_error.102 if to_unicode fails or surrogate error. Throws parse_error.103 if to_unicode fails.","title":"Exceptions"},{"location":"api/operator_gtgt/#complexity","text":"Linear in the length of the input. The parser is a predictive LL(1) parser.","title":"Complexity"},{"location":"api/operator_gtgt/#notes","text":"A UTF-8 byte order mark is silently ignored. 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 ; .","title":"Notes"},{"location":"api/operator_gtgt/#examples","text":"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!\" }","title":"Examples"},{"location":"api/operator_gtgt/#see-also","text":"accept - check if the input is valid JSON parse - deserialize from a compatible input","title":"See also"},{"location":"api/operator_gtgt/#version-history","text":"Added in version 1.0.0. Deprecated in version 3.0.0.","title":"Version history"},{"location":"api/operator_literal_json/","text":"nlohmann:: operator\"\"_json \u00b6 json operator \"\" _json ( const char * s , std :: size_t n ); 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 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` for details. Parameters \u00b6 s (in) a string representation of a JSON object n (in) length of string s Return value \u00b6 json value parsed from s Exceptions \u00b6 The function can throw anything that parse(s, s+n) would throw. Complexity \u00b6 Linear. Examples \u00b6 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\" } Version history \u00b6 Added in version 1.0.0. Moved to namespace nlohmann::literals::json_literals in 3.11.0.","title":"operator\"\"_json"},{"location":"api/operator_literal_json/#nlohmannoperator_json","text":"json operator \"\" _json ( const char * s , std :: size_t n ); 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 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` for details.","title":"nlohmann::operator\"\"_json"},{"location":"api/operator_literal_json/#parameters","text":"s (in) a string representation of a JSON object n (in) length of string s","title":"Parameters"},{"location":"api/operator_literal_json/#return-value","text":"json value parsed from s","title":"Return value"},{"location":"api/operator_literal_json/#exceptions","text":"The function can throw anything that parse(s, s+n) would throw.","title":"Exceptions"},{"location":"api/operator_literal_json/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/operator_literal_json/#examples","text":"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\" }","title":"Examples"},{"location":"api/operator_literal_json/#version-history","text":"Added in version 1.0.0. Moved to namespace nlohmann::literals::json_literals in 3.11.0.","title":"Version history"},{"location":"api/operator_literal_json_pointer/","text":"nlohmann:: operator\"\"_json_pointer \u00b6 json_pointer operator \"\" _json_pointer ( const char * s , std :: size_t n ); 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 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` for details. Parameters \u00b6 s (in) a string representation of a JSON Pointer n (in) length of string s Return value \u00b6 json_pointer value parsed from s Exceptions \u00b6 The function can throw anything that json_pointer::json_pointer would throw. Complexity \u00b6 Linear. Examples \u00b6 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 \u00b6 json_pointer - type to represent JSON Pointers Version history \u00b6 Added in version 2.0.0. Moved to namespace nlohmann::literals::json_literals in 3.11.0.","title":"operator\"\"_json_pointer"},{"location":"api/operator_literal_json_pointer/#nlohmannoperator_json_pointer","text":"json_pointer operator \"\" _json_pointer ( const char * s , std :: size_t n ); 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 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` for details.","title":"nlohmann::operator\"\"_json_pointer"},{"location":"api/operator_literal_json_pointer/#parameters","text":"s (in) a string representation of a JSON Pointer n (in) length of string s","title":"Parameters"},{"location":"api/operator_literal_json_pointer/#return-value","text":"json_pointer value parsed from s","title":"Return value"},{"location":"api/operator_literal_json_pointer/#exceptions","text":"The function can throw anything that json_pointer::json_pointer would throw.","title":"Exceptions"},{"location":"api/operator_literal_json_pointer/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/operator_literal_json_pointer/#examples","text":"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\"","title":"Examples"},{"location":"api/operator_literal_json_pointer/#see-also","text":"json_pointer - type to represent JSON Pointers","title":"See also"},{"location":"api/operator_literal_json_pointer/#version-history","text":"Added in version 2.0.0. Moved to namespace nlohmann::literals::json_literals in 3.11.0.","title":"Version history"},{"location":"api/operator_ltlt/","text":"nlohmann:: operator<<(basic_json), nlohmann:: operator<<(json_pointer) \u00b6 std :: ostream & operator << ( std :: ostream & o , const basic_json & j ); // (1) std :: ostream & operator << ( std :: ostream & o , const json_pointer & ptr ); // (2) Serialize the given JSON value j to the output stream o . The JSON value will be serialized using the dump 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. Write a string representation of the given JSON pointer ptr to the output stream o . The string representation is obtained using the to_string member function. Parameters \u00b6 o (in, out) stream to write to j (in) JSON value to serialize ptr (in) JSON pointer to write Return value \u00b6 the stream o Exceptions \u00b6 Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded. Note that unlike the dump member functions, no error_handler can be set. None. Complexity \u00b6 Linear. Notes \u00b6 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 \u00b6 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 poiner json :: json_pointer ptr ( \"/foo/bar/baz\" ); // write string representation to stream std :: cout << ptr << std :: endl ; } Output: / f oo/bar/baz Version history \u00b6 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. Added in version 3.11.0.","title":"operator<<(json_pointer)"},{"location":"api/operator_ltlt/#nlohmannoperatorbasic_json-nlohmannoperatorjson_pointer","text":"std :: ostream & operator << ( std :: ostream & o , const basic_json & j ); // (1) std :: ostream & operator << ( std :: ostream & o , const json_pointer & ptr ); // (2) Serialize the given JSON value j to the output stream o . The JSON value will be serialized using the dump 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. Write a string representation of the given JSON pointer ptr to the output stream o . The string representation is obtained using the to_string member function.","title":"nlohmann::operator<<(basic_json), nlohmann::operator<<(json_pointer)"},{"location":"api/operator_ltlt/#parameters","text":"o (in, out) stream to write to j (in) JSON value to serialize ptr (in) JSON pointer to write","title":"Parameters"},{"location":"api/operator_ltlt/#return-value","text":"the stream o","title":"Return value"},{"location":"api/operator_ltlt/#exceptions","text":"Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded. Note that unlike the dump member functions, no error_handler can be set. None.","title":"Exceptions"},{"location":"api/operator_ltlt/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/operator_ltlt/#notes","text":"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 ; .","title":"Notes"},{"location":"api/operator_ltlt/#examples","text":"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 poiner json :: json_pointer ptr ( \"/foo/bar/baz\" ); // write string representation to stream std :: cout << ptr << std :: endl ; } Output: / f oo/bar/baz","title":"Examples"},{"location":"api/operator_ltlt/#version-history","text":"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. Added in version 3.11.0.","title":"Version history"},{"location":"api/ordered_json/","text":"nlohmann:: ordered_json \u00b6 using ordered_json = basic_json < ordered_map > ; This type preserves the insertion order of object keys. Examples \u00b6 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 \u00b6 ordered_map Object Order Version history \u00b6 Since version 3.9.0.","title":"ordered_json"},{"location":"api/ordered_json/#nlohmannordered_json","text":"using ordered_json = basic_json < ordered_map > ; This type preserves the insertion order of object keys.","title":"nlohmann::ordered_json"},{"location":"api/ordered_json/#examples","text":"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 }","title":"Examples"},{"location":"api/ordered_json/#see-also","text":"ordered_map Object Order","title":"See also"},{"location":"api/ordered_json/#version-history","text":"Since version 3.9.0.","title":"Version history"},{"location":"api/ordered_map/","text":"nlohmann:: ordered_map \u00b6 template < class Key , class T , class IgnoredLess = std :: less < Key > , class Allocator = std :: allocator < std :: pair < const Key , T >>> struct ordered_map : std :: vector < std :: pair < const Key , T > , Allocator > ; A minimal map-like container that preserves insertion order for use within nlohmann::ordered_json ( nlohmann::basic_json ). Template parameters \u00b6 Key key type T mapped type IgnoredLess comparison function (ignored and only added to ensure compatibility with std :: map ) Allocator allocator type Member types \u00b6 key_type - key type ( Key ) mapped_type - mapped type ( T ) Container - base container type ( std :: vector < std :: pair < const Key , T > , Allocator > ) iterator const_iterator size_type value_type key_compare - key comparison function std :: equal_to < Key > // until C++14 std :: equal_to <> // since C++14 Member functions \u00b6 (constructor) (destructor) emplace operator[] at erase count find insert Examples \u00b6 Example The example shows the different behavior of std::map and nlohmann::ordered_map . #include #include // simple output function template < typename Map > 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 < std :: string , std :: string > m_ordered ; m_ordered [ \"one\" ] = \"eins\" ; m_ordered [ \"two\" ] = \"zwei\" ; m_ordered [ \"three\" ] = \"drei\" ; std :: map < std :: string , std :: string > 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 = { o ne : ei ns t wo : zwei t hree : drei } m_s t d = { o ne : ei ns t hree : drei t wo : zwei } m_ordered = { t wo : zwei t hree : drei o ne : ei ns } m_s t d = { o ne : ei ns t hree : drei t wo : zwei } See also \u00b6 ordered_json Version history \u00b6 Added in version 3.9.0 to implement nlohmann::ordered_json . Added key_compare member in version 3.11.0.","title":"ordered_map"},{"location":"api/ordered_map/#nlohmannordered_map","text":"template < class Key , class T , class IgnoredLess = std :: less < Key > , class Allocator = std :: allocator < std :: pair < const Key , T >>> struct ordered_map : std :: vector < std :: pair < const Key , T > , Allocator > ; A minimal map-like container that preserves insertion order for use within nlohmann::ordered_json ( nlohmann::basic_json ).","title":"nlohmann::ordered_map"},{"location":"api/ordered_map/#template-parameters","text":"Key key type T mapped type IgnoredLess comparison function (ignored and only added to ensure compatibility with std :: map ) Allocator allocator type","title":"Template parameters"},{"location":"api/ordered_map/#member-types","text":"key_type - key type ( Key ) mapped_type - mapped type ( T ) Container - base container type ( std :: vector < std :: pair < const Key , T > , Allocator > ) iterator const_iterator size_type value_type key_compare - key comparison function std :: equal_to < Key > // until C++14 std :: equal_to <> // since C++14","title":"Member types"},{"location":"api/ordered_map/#member-functions","text":"(constructor) (destructor) emplace operator[] at erase count find insert","title":"Member functions"},{"location":"api/ordered_map/#examples","text":"Example The example shows the different behavior of std::map and nlohmann::ordered_map . #include #include // simple output function template < typename Map > 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 < std :: string , std :: string > m_ordered ; m_ordered [ \"one\" ] = \"eins\" ; m_ordered [ \"two\" ] = \"zwei\" ; m_ordered [ \"three\" ] = \"drei\" ; std :: map < std :: string , std :: string > 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 = { o ne : ei ns t wo : zwei t hree : drei } m_s t d = { o ne : ei ns t hree : drei t wo : zwei } m_ordered = { t wo : zwei t hree : drei o ne : ei ns } m_s t d = { o ne : ei ns t hree : drei t wo : zwei }","title":"Examples"},{"location":"api/ordered_map/#see-also","text":"ordered_json","title":"See also"},{"location":"api/ordered_map/#version-history","text":"Added in version 3.9.0 to implement nlohmann::ordered_json . Added key_compare member in version 3.11.0.","title":"Version history"},{"location":"api/adl_serializer/","text":"nlohmann:: adl_serializer \u00b6 template < typename , typename > struct adl_serializer ; Serializer that uses ADL ( Argument-Dependent Lookup ) to choose to_json / from_json functions from the types' namespaces. It is implemented similar to template < typename ValueType > struct adl_serializer { template < typename BasicJsonType > static void to_json ( BasicJsonType & j , const T & value ) { // calls the \"to_json\" method in T's namespace } template < typename BasicJsonType > static void from_json ( const BasicJsonType & j , T & value ) { // same thing, but with the \"from_json\" method } }; Member functions \u00b6 from_json - convert a JSON value to any value type to_json - convert any value type to a JSON value Version history \u00b6 Added in version 2.1.0.","title":"Overview"},{"location":"api/adl_serializer/#nlohmannadl_serializer","text":"template < typename , typename > struct adl_serializer ; Serializer that uses ADL ( Argument-Dependent Lookup ) to choose to_json / from_json functions from the types' namespaces. It is implemented similar to template < typename ValueType > struct adl_serializer { template < typename BasicJsonType > static void to_json ( BasicJsonType & j , const T & value ) { // calls the \"to_json\" method in T's namespace } template < typename BasicJsonType > static void from_json ( const BasicJsonType & j , T & value ) { // same thing, but with the \"from_json\" method } };","title":"nlohmann::adl_serializer"},{"location":"api/adl_serializer/#member-functions","text":"from_json - convert a JSON value to any value type to_json - convert any value type to a JSON value","title":"Member functions"},{"location":"api/adl_serializer/#version-history","text":"Added in version 2.1.0.","title":"Version history"},{"location":"api/adl_serializer/from_json/","text":"nlohmann::adl_serializer:: from_json \u00b6 // (1) template < typename BasicJsonType , typename TargetType = ValueType > static auto from_json ( BasicJsonType && j , TargetType & val ) noexcept ( noexcept ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), val ))) -> decltype ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), val ), void ()) // (2) template < typename BasicJsonType , typename TargetType = ValueType > static auto from_json ( BasicJsonType && j ) noexcept ( noexcept ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), detail :: identity_tag < TargetType > {}))) -> decltype ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), detail :: identity_tag < TargetType > {})) This function is usually called by the get() function of the basic_json class (either explicitly or via the conversion operators). This function is chosen for default-constructible value types. This function is chosen for value types which are not default-constructible. Parameters \u00b6 j (in) JSON value to read from val (out) value to write to Return value \u00b6 Copy of the JSON value, converted to ValueType Examples \u00b6 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 < ns :: person > (); std :: cout << p . name << \" (\" << p . age << \") lives in \" << p . address << std :: endl ; } Output: Ned Fla n ders ( 60 ) lives i n 744 Evergree n 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 < ns :: person > { 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 < ns :: person > (); std :: cout << p . name << \" (\" << p . age << \") lives in \" << p . address << std :: endl ; } Output: Ned Fla n ders ( 60 ) lives i n 744 Evergree n Terrace See also \u00b6 to_json Version history \u00b6 Added in version 2.1.0.","title":"from_json"},{"location":"api/adl_serializer/from_json/#nlohmannadl_serializerfrom_json","text":"// (1) template < typename BasicJsonType , typename TargetType = ValueType > static auto from_json ( BasicJsonType && j , TargetType & val ) noexcept ( noexcept ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), val ))) -> decltype ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), val ), void ()) // (2) template < typename BasicJsonType , typename TargetType = ValueType > static auto from_json ( BasicJsonType && j ) noexcept ( noexcept ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), detail :: identity_tag < TargetType > {}))) -> decltype ( :: nlohmann :: from_json ( std :: forward < BasicJsonType > ( j ), detail :: identity_tag < TargetType > {})) This function is usually called by the get() function of the basic_json class (either explicitly or via the conversion operators). This function is chosen for default-constructible value types. This function is chosen for value types which are not default-constructible.","title":"nlohmann::adl_serializer::from_json"},{"location":"api/adl_serializer/from_json/#parameters","text":"j (in) JSON value to read from val (out) value to write to","title":"Parameters"},{"location":"api/adl_serializer/from_json/#return-value","text":"Copy of the JSON value, converted to ValueType","title":"Return value"},{"location":"api/adl_serializer/from_json/#examples","text":"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 < ns :: person > (); std :: cout << p . name << \" (\" << p . age << \") lives in \" << p . address << std :: endl ; } Output: Ned Fla n ders ( 60 ) lives i n 744 Evergree n 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 < ns :: person > { 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 < ns :: person > (); std :: cout << p . name << \" (\" << p . age << \") lives in \" << p . address << std :: endl ; } Output: Ned Fla n ders ( 60 ) lives i n 744 Evergree n Terrace","title":"Examples"},{"location":"api/adl_serializer/from_json/#see-also","text":"to_json","title":"See also"},{"location":"api/adl_serializer/from_json/#version-history","text":"Added in version 2.1.0.","title":"Version history"},{"location":"api/adl_serializer/to_json/","text":"nlohmann::adl_serializer:: to_json \u00b6 template < typename BasicJsonType , typename TargetType = ValueType > static auto to_json ( BasicJsonType & j , TargetType && val ) noexcept ( noexcept ( :: nlohmann :: to_json ( j , std :: forward < TargetType > ( val )))) -> decltype ( :: nlohmann :: to_json ( j , std :: forward < TargetType > ( val )), void ()) This function is usually called by the constructors of the basic_json class. Parameters \u00b6 j (out) JSON value to write to val (in) value to read from Examples \u00b6 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 \u00b6 from_json Version history \u00b6 Added in version 2.1.0.","title":"to_json"},{"location":"api/adl_serializer/to_json/#nlohmannadl_serializerto_json","text":"template < typename BasicJsonType , typename TargetType = ValueType > static auto to_json ( BasicJsonType & j , TargetType && val ) noexcept ( noexcept ( :: nlohmann :: to_json ( j , std :: forward < TargetType > ( val )))) -> decltype ( :: nlohmann :: to_json ( j , std :: forward < TargetType > ( val )), void ()) This function is usually called by the constructors of the basic_json class.","title":"nlohmann::adl_serializer::to_json"},{"location":"api/adl_serializer/to_json/#parameters","text":"j (out) JSON value to write to val (in) value to read from","title":"Parameters"},{"location":"api/adl_serializer/to_json/#examples","text":"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\" }","title":"Examples"},{"location":"api/adl_serializer/to_json/#see-also","text":"from_json","title":"See also"},{"location":"api/adl_serializer/to_json/#version-history","text":"Added in version 2.1.0.","title":"Version history"},{"location":"api/basic_json/","text":"nlohmann:: basic_json \u00b6 Defined in header template < template < typename U , typename V , typename ... Args > class ObjectType = std :: map , template < typename U , typename ... Args > 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 < typename U > class AllocatorType = std :: allocator , template < typename T , typename SFINAE = void > class JSONSerializer = adl_serializer , class BinaryType = std :: vector < std :: uint8_t , class CustomBaseClass = void > > class basic_json ; Template parameters \u00b6 Template parameter Description Derived type ObjectType type for JSON objects object_t ArrayType type for JSON arrays array_t StringType type for JSON strings and object keys string_t BooleanType type for JSON booleans boolean_t NumberIntegerType type for JSON integer numbers number_integer_t NumberUnsignedType type for JSON unsigned integer numbers number_unsigned_t NumberFloatType type for JSON floating-point numbers number_float_t AllocatorType type of the allocator to use JSONSerializer the serializer to resolve internal calls to to_json() and from_json() json_serializer BinaryType type for binary arrays binary_t CustomBaseClass extension point for user code json_base_class_t Specializations \u00b6 json - default specialization ordered_json - specialization that maintains the insertion order of object keys Iterator invalidation \u00b6 Todo Requirements \u00b6 The class satisfies the following concept requirements: Basic \u00b6 DefaultConstructible : JSON values can be default constructed. The result will be a JSON null value. MoveConstructible : A JSON value can be constructed from an rvalue argument. CopyConstructible : A JSON value can be copy-constructed from an lvalue expression. MoveAssignable : A JSON value can be assigned from an rvalue argument. CopyAssignable : A JSON value can be copy-assigned from an lvalue expression. Destructible : JSON values can be destructed. Layout \u00b6 StandardLayoutType : JSON values have 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 \u00b6 EqualityComparable : JSON values can be compared with == , see operator== . LessThanComparable : JSON values can be compared with < , see operator< . Swappable : Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of other compatible types, using unqualified function swap . NullablePointer : JSON values can be compared against std::nullptr_t objects which are used to model the null value. Container \u00b6 Container : JSON values can be used like STL containers and provide iterator access. ReversibleContainer : JSON values can be used like STL containers and provide reverse iterator access. Member types \u00b6 adl_serializer - the default serializer value_t - the JSON type enumeration json_pointer - JSON Pointer implementation json_serializer - type of the serializer to for conversions from/to JSON error_handler_t - type to choose behavior on decoding errors cbor_tag_handler_t - type to choose how to handle CBOR tags initializer_list_t - type for initializer lists of basic_json values input_format_t - type to choose the format to parse json_sax_t - type for SAX events Exceptions \u00b6 exception - general exception of the basic_json class parse_error - exception indicating a parse error invalid_iterator - exception indicating errors with iterators type_error - exception indicating executing a member function with a wrong type out_of_range - exception indicating access out of the defined range other_error - exception indicating other library errors Container types \u00b6 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 < basic_json > pointer std :: allocator_traits < allocator_type >:: pointer const_pointer std :: allocator_traits < allocator_type >:: const_pointer iterator LegacyBidirectionalIterator const_iterator constant LegacyBidirectionalIterator reverse_iterator reverse iterator, derived from iterator const_reverse_iterator reverse iterator, derived from const_iterator iteration_proxy helper type for items function JSON value data types \u00b6 array_t - type for arrays binary_t - type for binary arrays boolean_t - type for booleans default_object_comparator_t - default comparator for objects number_float_t - type for numbers (floating-point) number_integer_t - type for numbers (integer) number_unsigned_t - type for numbers (unsigned) object_comparator_t - comparator for objects object_t - type for objects string_t - type for strings Parser callback \u00b6 parse_event_t - parser event types parser_callback_t - per-element parser callback type Member functions \u00b6 (constructor) (destructor) operator= - copy assignment array ( static ) - explicitly create an array binary ( static ) - explicitly create a binary array object ( static ) - explicitly create an object Object inspection \u00b6 Functions to inspect the type of a JSON value. type - return the type of the JSON value operator value_t - return the type of the JSON value type_name - return the type as string is_primitive - return whether type is primitive is_structured - return whether type is structured is_null - return whether value is null is_boolean - return whether value is a boolean is_number - return whether value is a number is_number_integer - return whether value is an integer number is_number_unsigned - return whether value is an unsigned integer number is_number_float - return whether value is a floating-point number is_object - return whether value is an object is_array - return whether value is an array is_string - return whether value is a string is_binary - return whether value is a binary array is_discarded - return whether value is discarded Value access \u00b6 Direct access to the stored value of a JSON value. get - get a value get_to - get a value and write it to a destination get_ptr - get a pointer value get_ref - get a reference value operator ValueType - get a value get_binary - get a binary value Element access \u00b6 Access to the JSON value at - access specified element with bounds checking operator[] - access specified element value - access specified object element with default value front - access the first element back - access the last element Lookup \u00b6 find - find an element in a JSON object count - returns the number of occurrences of a key in a JSON object contains - check the existence of an element in a JSON object Iterators \u00b6 begin - returns an iterator to the first element cbegin - returns a const iterator to the first element end - returns an iterator to one past the last element cend - returns a const iterator to one past the last element rbegin - returns an iterator to the reverse-beginning rend - returns an iterator to the reverse-end crbegin - returns a const iterator to the reverse-beginning crend - returns a const iterator to the reverse-end items - wrapper to access iterator member functions in range-based for Capacity \u00b6 empty - checks whether the container is empty size - returns the number of elements max_size - returns the maximum possible number of elements Modifiers \u00b6 clear - clears the contents push_back - add a value to an array/object operator+= - add a value to an array/object emplace_back - add a value to an array emplace - add a value to an object if key does not exist erase - remove elements insert - inserts elements update - updates a JSON object from another object, overwriting existing keys swap - exchanges the values Lexicographical comparison operators \u00b6 operator== - comparison: equal operator!= - comparison: not equal operator< - comparison: less than operator> - comparison: greater than operator<= - comparison: less than or equal operator>= - comparison: greater than or equal operator<=> - comparison: 3-way Serialization / Dumping \u00b6 dump - serialization Deserialization / Parsing \u00b6 parse ( static ) - deserialize from a compatible input accept ( static ) - check if the input is valid JSON sax_parse ( static ) - generate SAX events JSON Pointer functions \u00b6 flatten - return flattened JSON value unflatten - unflatten a previously flattened JSON value JSON Patch functions \u00b6 patch - applies a JSON patch patch_inplace - applies a JSON patch in place diff ( static ) - creates a diff as a JSON patch JSON Merge Patch functions \u00b6 merge_patch - applies a JSON Merge Patch Static functions \u00b6 meta - returns version information on the library get_allocator - returns the allocator associated with the container Binary formats \u00b6 from_bjdata ( static ) - create a JSON value from an input in BJData format from_bson ( static ) - create a JSON value from an input in BSON format from_cbor ( static ) - create a JSON value from an input in CBOR format from_msgpack ( static ) - create a JSON value from an input in MessagePack format from_ubjson ( static ) - create a JSON value from an input in UBJSON format to_bjdata ( static ) - create a BJData serialization of a given JSON value to_bson ( static ) - create a BSON serialization of a given JSON value to_cbor ( static ) - create a CBOR serialization of a given JSON value to_msgpack ( static ) - create a MessagePack serialization of a given JSON value to_ubjson ( static ) - create a UBJSON serialization of a given JSON value Non-member functions \u00b6 operator<<(std::ostream&) - serialize to stream operator>>(std::istream&) - deserialize from stream to_string - user-defined to_string function for JSON values Literals \u00b6 operator\"\"_json - user-defined string literal for JSON values Helper classes \u00b6 std::hash - return a hash value for a JSON object std::swap - exchanges the values of two JSON objects Examples \u00b6 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 \u00b6 RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format Version history \u00b6 Added in version 1.0.0.","title":"Overview"},{"location":"api/basic_json/#nlohmannbasic_json","text":"Defined in header template < template < typename U , typename V , typename ... Args > class ObjectType = std :: map , template < typename U , typename ... Args > 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 < typename U > class AllocatorType = std :: allocator , template < typename T , typename SFINAE = void > class JSONSerializer = adl_serializer , class BinaryType = std :: vector < std :: uint8_t , class CustomBaseClass = void > > class basic_json ;","title":"nlohmann::basic_json"},{"location":"api/basic_json/#template-parameters","text":"Template parameter Description Derived type ObjectType type for JSON objects object_t ArrayType type for JSON arrays array_t StringType type for JSON strings and object keys string_t BooleanType type for JSON booleans boolean_t NumberIntegerType type for JSON integer numbers number_integer_t NumberUnsignedType type for JSON unsigned integer numbers number_unsigned_t NumberFloatType type for JSON floating-point numbers number_float_t AllocatorType type of the allocator to use JSONSerializer the serializer to resolve internal calls to to_json() and from_json() json_serializer BinaryType type for binary arrays binary_t CustomBaseClass extension point for user code json_base_class_t","title":"Template parameters"},{"location":"api/basic_json/#specializations","text":"json - default specialization ordered_json - specialization that maintains the insertion order of object keys","title":"Specializations"},{"location":"api/basic_json/#iterator-invalidation","text":"Todo","title":"Iterator invalidation"},{"location":"api/basic_json/#requirements","text":"The class satisfies the following concept requirements:","title":"Requirements"},{"location":"api/basic_json/#basic","text":"DefaultConstructible : JSON values can be default constructed. The result will be a JSON null value. MoveConstructible : A JSON value can be constructed from an rvalue argument. CopyConstructible : A JSON value can be copy-constructed from an lvalue expression. MoveAssignable : A JSON value can be assigned from an rvalue argument. CopyAssignable : A JSON value can be copy-assigned from an lvalue expression. Destructible : JSON values can be destructed.","title":"Basic"},{"location":"api/basic_json/#layout","text":"StandardLayoutType : JSON values have standard layout : All non-static data members are private and standard layout types, the class has no virtual functions or (virtual) base classes.","title":"Layout"},{"location":"api/basic_json/#library-wide","text":"EqualityComparable : JSON values can be compared with == , see operator== . LessThanComparable : JSON values can be compared with < , see operator< . Swappable : Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of other compatible types, using unqualified function swap . NullablePointer : JSON values can be compared against std::nullptr_t objects which are used to model the null value.","title":"Library-wide"},{"location":"api/basic_json/#container","text":"Container : JSON values can be used like STL containers and provide iterator access. ReversibleContainer : JSON values can be used like STL containers and provide reverse iterator access.","title":"Container"},{"location":"api/basic_json/#member-types","text":"adl_serializer - the default serializer value_t - the JSON type enumeration json_pointer - JSON Pointer implementation json_serializer - type of the serializer to for conversions from/to JSON error_handler_t - type to choose behavior on decoding errors cbor_tag_handler_t - type to choose how to handle CBOR tags initializer_list_t - type for initializer lists of basic_json values input_format_t - type to choose the format to parse json_sax_t - type for SAX events","title":"Member types"},{"location":"api/basic_json/#exceptions","text":"exception - general exception of the basic_json class parse_error - exception indicating a parse error invalid_iterator - exception indicating errors with iterators type_error - exception indicating executing a member function with a wrong type out_of_range - exception indicating access out of the defined range other_error - exception indicating other library errors","title":"Exceptions"},{"location":"api/basic_json/#container-types","text":"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 < basic_json > pointer std :: allocator_traits < allocator_type >:: pointer const_pointer std :: allocator_traits < allocator_type >:: const_pointer iterator LegacyBidirectionalIterator const_iterator constant LegacyBidirectionalIterator reverse_iterator reverse iterator, derived from iterator const_reverse_iterator reverse iterator, derived from const_iterator iteration_proxy helper type for items function","title":"Container types"},{"location":"api/basic_json/#json-value-data-types","text":"array_t - type for arrays binary_t - type for binary arrays boolean_t - type for booleans default_object_comparator_t - default comparator for objects number_float_t - type for numbers (floating-point) number_integer_t - type for numbers (integer) number_unsigned_t - type for numbers (unsigned) object_comparator_t - comparator for objects object_t - type for objects string_t - type for strings","title":"JSON value data types"},{"location":"api/basic_json/#parser-callback","text":"parse_event_t - parser event types parser_callback_t - per-element parser callback type","title":"Parser callback"},{"location":"api/basic_json/#member-functions","text":"(constructor) (destructor) operator= - copy assignment array ( static ) - explicitly create an array binary ( static ) - explicitly create a binary array object ( static ) - explicitly create an object","title":"Member functions"},{"location":"api/basic_json/#object-inspection","text":"Functions to inspect the type of a JSON value. type - return the type of the JSON value operator value_t - return the type of the JSON value type_name - return the type as string is_primitive - return whether type is primitive is_structured - return whether type is structured is_null - return whether value is null is_boolean - return whether value is a boolean is_number - return whether value is a number is_number_integer - return whether value is an integer number is_number_unsigned - return whether value is an unsigned integer number is_number_float - return whether value is a floating-point number is_object - return whether value is an object is_array - return whether value is an array is_string - return whether value is a string is_binary - return whether value is a binary array is_discarded - return whether value is discarded","title":"Object inspection"},{"location":"api/basic_json/#value-access","text":"Direct access to the stored value of a JSON value. get - get a value get_to - get a value and write it to a destination get_ptr - get a pointer value get_ref - get a reference value operator ValueType - get a value get_binary - get a binary value","title":"Value access"},{"location":"api/basic_json/#element-access","text":"Access to the JSON value at - access specified element with bounds checking operator[] - access specified element value - access specified object element with default value front - access the first element back - access the last element","title":"Element access"},{"location":"api/basic_json/#lookup","text":"find - find an element in a JSON object count - returns the number of occurrences of a key in a JSON object contains - check the existence of an element in a JSON object","title":"Lookup"},{"location":"api/basic_json/#iterators","text":"begin - returns an iterator to the first element cbegin - returns a const iterator to the first element end - returns an iterator to one past the last element cend - returns a const iterator to one past the last element rbegin - returns an iterator to the reverse-beginning rend - returns an iterator to the reverse-end crbegin - returns a const iterator to the reverse-beginning crend - returns a const iterator to the reverse-end items - wrapper to access iterator member functions in range-based for","title":"Iterators"},{"location":"api/basic_json/#capacity","text":"empty - checks whether the container is empty size - returns the number of elements max_size - returns the maximum possible number of elements","title":"Capacity"},{"location":"api/basic_json/#modifiers","text":"clear - clears the contents push_back - add a value to an array/object operator+= - add a value to an array/object emplace_back - add a value to an array emplace - add a value to an object if key does not exist erase - remove elements insert - inserts elements update - updates a JSON object from another object, overwriting existing keys swap - exchanges the values","title":"Modifiers"},{"location":"api/basic_json/#lexicographical-comparison-operators","text":"operator== - comparison: equal operator!= - comparison: not equal operator< - comparison: less than operator> - comparison: greater than operator<= - comparison: less than or equal operator>= - comparison: greater than or equal operator<=> - comparison: 3-way","title":"Lexicographical comparison operators"},{"location":"api/basic_json/#serialization-dumping","text":"dump - serialization","title":"Serialization / Dumping"},{"location":"api/basic_json/#deserialization-parsing","text":"parse ( static ) - deserialize from a compatible input accept ( static ) - check if the input is valid JSON sax_parse ( static ) - generate SAX events","title":"Deserialization / Parsing"},{"location":"api/basic_json/#json-pointer-functions","text":"flatten - return flattened JSON value unflatten - unflatten a previously flattened JSON value","title":"JSON Pointer functions"},{"location":"api/basic_json/#json-patch-functions","text":"patch - applies a JSON patch patch_inplace - applies a JSON patch in place diff ( static ) - creates a diff as a JSON patch","title":"JSON Patch functions"},{"location":"api/basic_json/#json-merge-patch-functions","text":"merge_patch - applies a JSON Merge Patch","title":"JSON Merge Patch functions"},{"location":"api/basic_json/#static-functions","text":"meta - returns version information on the library get_allocator - returns the allocator associated with the container","title":"Static functions"},{"location":"api/basic_json/#binary-formats","text":"from_bjdata ( static ) - create a JSON value from an input in BJData format from_bson ( static ) - create a JSON value from an input in BSON format from_cbor ( static ) - create a JSON value from an input in CBOR format from_msgpack ( static ) - create a JSON value from an input in MessagePack format from_ubjson ( static ) - create a JSON value from an input in UBJSON format to_bjdata ( static ) - create a BJData serialization of a given JSON value to_bson ( static ) - create a BSON serialization of a given JSON value to_cbor ( static ) - create a CBOR serialization of a given JSON value to_msgpack ( static ) - create a MessagePack serialization of a given JSON value to_ubjson ( static ) - create a UBJSON serialization of a given JSON value","title":"Binary formats"},{"location":"api/basic_json/#non-member-functions","text":"operator<<(std::ostream&) - serialize to stream operator>>(std::istream&) - deserialize from stream to_string - user-defined to_string function for JSON values","title":"Non-member functions"},{"location":"api/basic_json/#literals","text":"operator\"\"_json - user-defined string literal for JSON values","title":"Literals"},{"location":"api/basic_json/#helper-classes","text":"std::hash - return a hash value for a JSON object std::swap - exchanges the values of two JSON objects","title":"Helper classes"},{"location":"api/basic_json/#examples","text":"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 }","title":"Examples"},{"location":"api/basic_json/#see-also","text":"RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format","title":"See also"},{"location":"api/basic_json/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/accept/","text":"nlohmann::basic_json:: accept \u00b6 // (1) template < typename InputType > static bool accept ( InputType && i , const bool ignore_comments = false ); // (2) template < typename IteratorType > static bool accept ( IteratorType first , IteratorType last , const bool ignore_comments = false ); Checks whether the input is valid JSON. Reads from a compatible input. Reads 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. Unlike the parse function, this function neither throws an exception in case of invalid JSON input (i.e., a parse error) nor creates diagnostic information. Template parameters \u00b6 InputType A compatible input, for instance: an std::istream object a FILE pointer (must not be null) a C-style array of characters a pointer to a null-terminated string of single byte characters 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 \u00b6 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) first (in) iterator to start of character range last (in) iterator to end of character range Return value \u00b6 Whether the input is valid JSON. Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the length of the input. The parser is a predictive LL(1) parser. Notes \u00b6 (1) A UTF-8 byte order mark is silently ignored. Runtime assertion The precondition that a passed FILE pointer must not be null is enforced with a runtime assertion . Examples \u00b6 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 \u00b6 parse - deserialize from a compatible input operator>> - deserialize from stream Version history \u00b6 Added in version 3.0.0. Ignoring comments via ignore_comments added in version 3.9.0. 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.","title":"accept"},{"location":"api/basic_json/accept/#nlohmannbasic_jsonaccept","text":"// (1) template < typename InputType > static bool accept ( InputType && i , const bool ignore_comments = false ); // (2) template < typename IteratorType > static bool accept ( IteratorType first , IteratorType last , const bool ignore_comments = false ); Checks whether the input is valid JSON. Reads from a compatible input. Reads 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. Unlike the parse function, this function neither throws an exception in case of invalid JSON input (i.e., a parse error) nor creates diagnostic information.","title":"nlohmann::basic_json::accept"},{"location":"api/basic_json/accept/#template-parameters","text":"InputType A compatible input, for instance: an std::istream object a FILE pointer (must not be null) a C-style array of characters a pointer to a null-terminated string of single byte characters 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","title":"Template parameters"},{"location":"api/basic_json/accept/#parameters","text":"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) first (in) iterator to start of character range last (in) iterator to end of character range","title":"Parameters"},{"location":"api/basic_json/accept/#return-value","text":"Whether the input is valid JSON.","title":"Return value"},{"location":"api/basic_json/accept/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/accept/#complexity","text":"Linear in the length of the input. The parser is a predictive LL(1) parser.","title":"Complexity"},{"location":"api/basic_json/accept/#notes","text":"(1) A UTF-8 byte order mark is silently ignored. Runtime assertion The precondition that a passed FILE pointer must not be null is enforced with a runtime assertion .","title":"Notes"},{"location":"api/basic_json/accept/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/accept/#see-also","text":"parse - deserialize from a compatible input operator>> - deserialize from stream","title":"See also"},{"location":"api/basic_json/accept/#version-history","text":"Added in version 3.0.0. Ignoring comments via ignore_comments added in version 3.9.0. 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.","title":"Version history"},{"location":"api/basic_json/array/","text":"nlohmann::basic_json:: array \u00b6 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 \u00b6 init (in) initializer list with JSON values to create an array from (optional) Return value \u00b6 JSON array value Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the size of init . Notes \u00b6 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) ). These cases are: 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 creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty object Examples \u00b6 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 \u00b6 basic_json(initializer_list_t) - create a JSON value from an initializer list object - create a JSON object value from an initializer list Version history \u00b6 Added in version 1.0.0.","title":"array"},{"location":"api/basic_json/array/#nlohmannbasic_jsonarray","text":"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.","title":"nlohmann::basic_json::array"},{"location":"api/basic_json/array/#parameters","text":"init (in) initializer list with JSON values to create an array from (optional)","title":"Parameters"},{"location":"api/basic_json/array/#return-value","text":"JSON array value","title":"Return value"},{"location":"api/basic_json/array/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/array/#complexity","text":"Linear in the size of init .","title":"Complexity"},{"location":"api/basic_json/array/#notes","text":"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) ). These cases are: 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 creating an empty array -- passing the empty initializer list to the initializer list constructor yields an empty object","title":"Notes"},{"location":"api/basic_json/array/#examples","text":"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 ]]","title":"Examples"},{"location":"api/basic_json/array/#see-also","text":"basic_json(initializer_list_t) - create a JSON value from an initializer list object - create a JSON object value from an initializer list","title":"See also"},{"location":"api/basic_json/array/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/array_t/","text":"nlohmann::basic_json:: array_t \u00b6 using array_t = ArrayType < basic_json , AllocatorType < basic_json >> ; The type used to store JSON arrays. RFC 8259 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 \u00b6 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 \u00b6 Default type \u00b6 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 < basic_json > // allocator_type > Limits \u00b6 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 \u00b6 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 \u00b6 Example The following code shows that array_t is by default, a typedef to std :: vector < nlohmann :: json > . #include #include #include using json = nlohmann :: json ; int main () { std :: cout << std :: boolalpha << std :: is_same < std :: vector < json > , json :: array_t >:: value << std :: endl ; } Output: true Version history \u00b6 Added in version 1.0.0.","title":"array_t"},{"location":"api/basic_json/array_t/#nlohmannbasic_jsonarray_t","text":"using array_t = ArrayType < basic_json , AllocatorType < basic_json >> ; The type used to store JSON arrays. RFC 8259 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.","title":"nlohmann::basic_json::array_t"},{"location":"api/basic_json/array_t/#template-parameters","text":"ArrayType container type to store arrays (e.g., std::vector or std::list ) AllocatorType the allocator to use for objects (e.g., std::allocator )","title":"Template parameters"},{"location":"api/basic_json/array_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/array_t/#default-type","text":"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 < basic_json > // allocator_type >","title":"Default type"},{"location":"api/basic_json/array_t/#limits","text":"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.","title":"Limits"},{"location":"api/basic_json/array_t/#storage","text":"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.","title":"Storage"},{"location":"api/basic_json/array_t/#examples","text":"Example The following code shows that array_t is by default, a typedef to std :: vector < nlohmann :: json > . #include #include #include using json = nlohmann :: json ; int main () { std :: cout << std :: boolalpha << std :: is_same < std :: vector < json > , json :: array_t >:: value << std :: endl ; } Output: true","title":"Examples"},{"location":"api/basic_json/array_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/at/","text":"nlohmann::basic_json:: at \u00b6 // (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 < typename KeyType > reference at ( KeyType && key ); template < typename KeyType > const_reference at ( KeyType && key ) const ; // (4) reference at ( const json_pointer & ptr ); const_reference at ( const json_pointer & ptr ) const ; Returns a reference to the array element at specified location idx , with bounds checking. Returns a reference to the object element with specified key key , with bounds checking. 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. Returns a reference to the element at specified JSON pointer ptr , with bounds checking. Template parameters \u00b6 KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17). Parameters \u00b6 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 \u00b6 reference to the element at index idx reference to the element at key key reference to the element at key key reference to the element pointed to by ptr Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 The function can throw the following exceptions: Throws type_error.304 if the JSON value is not an array; in this case, calling at with an index makes no sense. See example below. Throws out_of_range.401 if the index idx is out of range of the array; that is, idx >= size() . See example below. The function can throw the following exceptions: Throws type_error.304 if the JSON value is not an object; in this case, calling at with a key makes no sense. See example below. Throws out_of_range.403 if the key key is not stored in the object; that is, find(key) == end() . See example below. See 2. The function can throw the following exceptions: Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. See example below. Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. See example below. Throws out_of_range.401 if an array index in the passed JSON pointer ptr is out of range. See example below. Throws out_of_range.402 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 example below. Throws out_of_range.403 if the JSON pointer describes a key of an object which cannot be found. See example below. Throws out_of_range.404 if the JSON pointer ptr can not be resolved. See example below. Complexity \u00b6 Constant. Logarithmic in the size of the container. Logarithmic in the size of the container. Logarithmic in the size of the container. Examples \u00b6 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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: \"third\" [ \"first\" , \"second\" , \"third\" , \"fourth\" ] [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 5 is ou t o f ra n ge 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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: \"third\" [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 5 is ou t o f ra n ge 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 ( 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 ( 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\" } [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' t he fast ' n o t f ou n d 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 ( 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 ( json :: out_of_range ) { std :: cout << \"out of range\" << '\\n' ; } } Output: \"il brutto\" [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g ou t o f ra n ge 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 ( 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 ( 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\" } [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' t he fast ' n o t f ou n d 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 ( 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 ( json :: out_of_range ) { std :: cout << \"out of range\" << '\\n' ; } } Output: \"il brutto\" [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g ou t o f ra n ge 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 ( 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 ( 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 ( 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 ( 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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: 1 \"foo\" [ 1 , 2 ] 2 \"bar\" [ 1 , 21 ] [ jso n .excep t io n .parse_error. 106 ] parse error : array i n dex ' 01 ' mus t n o t begi n wi t h ' 0 ' [ jso n .excep t io n .parse_error. 109 ] parse error : array i n dex 'o ne ' is n o t a nu mber [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 4 is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 402 ] array i n dex ' - ' ( 2 ) is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' f oo' n o t f ou n d [ jso n .excep t io n .ou t _o f _ra n ge. 404 ] u nres olved re feren ce t oke n ' f oo' 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 ( 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 ( 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 ( 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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: 1 \"foo\" [ 1 , 2 ] 2 [ jso n .excep t io n .parse_error. 109 ] parse error : array i n dex 'o ne ' is n o t a nu mber [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 4 is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 402 ] array i n dex ' - ' ( 2 ) is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' f oo' n o t f ou n d [ jso n .excep t io n .ou t _o f _ra n ge. 404 ] u nres olved re feren ce t oke n ' f oo' See also \u00b6 documentation on checked access see operator[] for unchecked access by reference see value for access with default value Version history \u00b6 Added in version 1.0.0. Added in version 1.0.0. Added in version 3.11.0. Added in version 2.0.0.","title":"at"},{"location":"api/basic_json/at/#nlohmannbasic_jsonat","text":"// (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 < typename KeyType > reference at ( KeyType && key ); template < typename KeyType > const_reference at ( KeyType && key ) const ; // (4) reference at ( const json_pointer & ptr ); const_reference at ( const json_pointer & ptr ) const ; Returns a reference to the array element at specified location idx , with bounds checking. Returns a reference to the object element with specified key key , with bounds checking. 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. Returns a reference to the element at specified JSON pointer ptr , with bounds checking.","title":"nlohmann::basic_json::at"},{"location":"api/basic_json/at/#template-parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17).","title":"Template parameters"},{"location":"api/basic_json/at/#parameters","text":"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","title":"Parameters"},{"location":"api/basic_json/at/#return-value","text":"reference to the element at index idx reference to the element at key key reference to the element at key key reference to the element pointed to by ptr","title":"Return value"},{"location":"api/basic_json/at/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/at/#exceptions","text":"The function can throw the following exceptions: Throws type_error.304 if the JSON value is not an array; in this case, calling at with an index makes no sense. See example below. Throws out_of_range.401 if the index idx is out of range of the array; that is, idx >= size() . See example below. The function can throw the following exceptions: Throws type_error.304 if the JSON value is not an object; in this case, calling at with a key makes no sense. See example below. Throws out_of_range.403 if the key key is not stored in the object; that is, find(key) == end() . See example below. See 2. The function can throw the following exceptions: Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. See example below. Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. See example below. Throws out_of_range.401 if an array index in the passed JSON pointer ptr is out of range. See example below. Throws out_of_range.402 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 example below. Throws out_of_range.403 if the JSON pointer describes a key of an object which cannot be found. See example below. Throws out_of_range.404 if the JSON pointer ptr can not be resolved. See example below.","title":"Exceptions"},{"location":"api/basic_json/at/#complexity","text":"Constant. Logarithmic in the size of the container. Logarithmic in the size of the container. Logarithmic in the size of the container.","title":"Complexity"},{"location":"api/basic_json/at/#examples","text":"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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: \"third\" [ \"first\" , \"second\" , \"third\" , \"fourth\" ] [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 5 is ou t o f ra n ge 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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: \"third\" [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 5 is ou t o f ra n ge 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 ( 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 ( 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\" } [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' t he fast ' n o t f ou n d 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 ( 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 ( json :: out_of_range ) { std :: cout << \"out of range\" << '\\n' ; } } Output: \"il brutto\" [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g ou t o f ra n ge 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 ( 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 ( 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\" } [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' t he fast ' n o t f ou n d 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 ( 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 ( json :: out_of_range ) { std :: cout << \"out of range\" << '\\n' ; } } Output: \"il brutto\" [ jso n .excep t io n . t ype_error. 304 ] ca nn o t use a t () wi t h s tr i n g ou t o f ra n ge 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 ( 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 ( 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 ( 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 ( 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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: 1 \"foo\" [ 1 , 2 ] 2 \"bar\" [ 1 , 21 ] [ jso n .excep t io n .parse_error. 106 ] parse error : array i n dex ' 01 ' mus t n o t begi n wi t h ' 0 ' [ jso n .excep t io n .parse_error. 109 ] parse error : array i n dex 'o ne ' is n o t a nu mber [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 4 is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 402 ] array i n dex ' - ' ( 2 ) is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' f oo' n o t f ou n d [ jso n .excep t io n .ou t _o f _ra n ge. 404 ] u nres olved re feren ce t oke n ' f oo' 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 ( 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 ( 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 ( 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 ( 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 ( json :: out_of_range & e ) { std :: cout << e . what () << '\\n' ; } } Output: 1 \"foo\" [ 1 , 2 ] 2 [ jso n .excep t io n .parse_error. 109 ] parse error : array i n dex 'o ne ' is n o t a nu mber [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 4 is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 402 ] array i n dex ' - ' ( 2 ) is ou t o f ra n ge [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' f oo' n o t f ou n d [ jso n .excep t io n .ou t _o f _ra n ge. 404 ] u nres olved re feren ce t oke n ' f oo'","title":"Examples"},{"location":"api/basic_json/at/#see-also","text":"documentation on checked access see operator[] for unchecked access by reference see value for access with default value","title":"See also"},{"location":"api/basic_json/at/#version-history","text":"Added in version 1.0.0. Added in version 1.0.0. Added in version 3.11.0. Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/back/","text":"nlohmann::basic_json:: back \u00b6 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 \u00b6 In case of a structured type (array or object), a reference to the last element is returned. In case of number, string, boolean, or binary values, a reference to the value is returned. Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 If the JSON value is null , exception invalid_iterator.214 is thrown. Complexity \u00b6 Constant. Notes \u00b6 Precondition The array or object must not be empty. Calling back on an empty array or object yields undefined behavior. Examples \u00b6 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 ( json :: invalid_iterator & e ) { std :: cout << e . what () << '\\n' ; } } Output: true 17 23.42 2 16 \"Hello, world\" [ jso n .excep t io n .i n valid_i terat or. 214 ] ca nn o t ge t value See also \u00b6 front to access the first element Version history \u00b6 Added in version 1.0.0. Adjusted code to return reference to binary values in version 3.8.0.","title":"back"},{"location":"api/basic_json/back/#nlohmannbasic_jsonback","text":"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 ;","title":"nlohmann::basic_json::back"},{"location":"api/basic_json/back/#return-value","text":"In case of a structured type (array or object), a reference to the last element is returned. In case of number, string, boolean, or binary values, a reference to the value is returned.","title":"Return value"},{"location":"api/basic_json/back/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/back/#exceptions","text":"If the JSON value is null , exception invalid_iterator.214 is thrown.","title":"Exceptions"},{"location":"api/basic_json/back/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/back/#notes","text":"Precondition The array or object must not be empty. Calling back on an empty array or object yields undefined behavior.","title":"Notes"},{"location":"api/basic_json/back/#examples","text":"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 ( json :: invalid_iterator & e ) { std :: cout << e . what () << '\\n' ; } } Output: true 17 23.42 2 16 \"Hello, world\" [ jso n .excep t io n .i n valid_i terat or. 214 ] ca nn o t ge t value","title":"Examples"},{"location":"api/basic_json/back/#see-also","text":"front to access the first element","title":"See also"},{"location":"api/basic_json/back/#version-history","text":"Added in version 1.0.0. Adjusted code to return reference to binary values in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/basic_json/","text":"nlohmann::basic_json:: basic_json \u00b6 // (1) basic_json ( const value_t v ); // (2) basic_json ( std :: nullptr_t = nullptr ) noexcept ; // (3) template < typename CompatibleType > basic_json ( CompatibleType && val ) noexcept ( noexcept ( JSONSerializer < U >:: to_json ( std :: declval < basic_json_t &> (), std :: forward < CompatibleType > ( val )))); // (4) template < typename BasicJsonType > 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 ; 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() . 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. 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 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 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_unsigned_t , number_float_t , 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. 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. 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: If the list is empty, an empty JSON object value {} is created. 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. 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: The empty initializer list is written as {} which is exactly an empty JSON object. 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. In all other cases, the initializer list could not be interpreted as JSON object type, so interpreting it as 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() and object() force array and object creation from initializer lists, respectively. Constructs a JSON array value by creating cnt copies of a passed value. In case cnt is 0 , an empty array is created. Constructs the JSON value with the contents of the range [first, last) . The semantics depends on the different types a JSON value can have: In case of a null type, invalid_iterator.206 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 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. Creates a copy of a given JSON value. 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 \u00b6 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 \u00b6 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) begin of the range to copy from (included) last (in) end of the range to copy from (excluded) other (in) the JSON value to copy/move Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes to any JSON value. No-throw guarantee: this constructor never throws exceptions. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. No-throw guarantee: this constructor never throws exceptions. Exceptions \u00b6 (none) The function does not throw exceptions. (none) (none) The function can throw the following exceptions: Throws type_error.301 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. (none) The function can throw the following exceptions: Throws invalid_iterator.201 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 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 example code below. Throws invalid_iterator.206 if iterators first and last belong to a null value. In this case, the range [first, last) is undefined. (none) The function does not throw exceptions. Complexity \u00b6 Constant. Constant. Usually linear in the size of the passed val , also depending on the implementation of the called to_json() method. Usually linear in the size of the passed val , also depending on the implementation of the called to_json() method. Linear in the size of the initializer list init . Linear in cnt . Linear in distance between first and last . Linear in the size of other . Constant. Notes \u00b6 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 . 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 . 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 \u00b6 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 < std :: string , int > c_map { { \"one\" , 1 }, { \"two\" , 2 }, { \"three\" , 3 } }; json j_map ( c_map ); // create an object from std::unordered_map std :: unordered_map < const char * , double > c_umap { { \"one\" , 1.2 }, { \"two\" , 2.3 }, { \"three\" , 3.4 } }; json j_umap ( c_umap ); // create an object from std::multimap std :: multimap < std :: string , bool > 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 < std :: string , bool > 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 < int > c_vector { 1 , 2 , 3 , 4 }; json j_vec ( c_vector ); // create an array from std::valarray std :: valarray < short > c_valarray { 10 , 9 , 8 , 7 }; json j_valarray ( c_valarray ); // create an array from std::deque std :: deque < double > c_deque { 1.2 , 2.3 , 3.4 , 5.6 }; json j_deque ( c_deque ); // create an array from std::list std :: list < bool > c_list { true , true , false , true }; json j_list ( c_list ); // create an array from std::forward_list std :: forward_list < std :: int64_t > c_flist { 12345678909876 , 23456789098765 , 34567890987654 , 45678909876543 }; json j_flist ( c_flist ); // create an array from std::array std :: array < unsigned long , 4 > c_array {{ 1 , 2 , 3 , 4 }}; json j_array ( c_array ); // create an array from std::set std :: set < std :: string > 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 < std :: string > 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 < std :: string > 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 < std :: string > 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 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 ( json :: invalid_iterator & e ) { std :: cout << e . what () << '\\n' ; } } Output: [ \"bravo\" , \"charly\" ] 42 { \"one\" : \"eins\" } [ jso n .excep t io n .i n valid_i terat or. 204 ] i terat ors ou t o f ra n ge 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 \u00b6 Since version 1.0.0. Since version 1.0.0. Since version 2.1.0. Since version 3.2.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0.","title":"(Constructor)"},{"location":"api/basic_json/basic_json/#nlohmannbasic_jsonbasic_json","text":"// (1) basic_json ( const value_t v ); // (2) basic_json ( std :: nullptr_t = nullptr ) noexcept ; // (3) template < typename CompatibleType > basic_json ( CompatibleType && val ) noexcept ( noexcept ( JSONSerializer < U >:: to_json ( std :: declval < basic_json_t &> (), std :: forward < CompatibleType > ( val )))); // (4) template < typename BasicJsonType > 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 ; 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() . 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. 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 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 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_unsigned_t , number_float_t , 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. 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. 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: If the list is empty, an empty JSON object value {} is created. 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. 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: The empty initializer list is written as {} which is exactly an empty JSON object. 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. In all other cases, the initializer list could not be interpreted as JSON object type, so interpreting it as 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() and object() force array and object creation from initializer lists, respectively. Constructs a JSON array value by creating cnt copies of a passed value. In case cnt is 0 , an empty array is created. Constructs the JSON value with the contents of the range [first, last) . The semantics depends on the different types a JSON value can have: In case of a null type, invalid_iterator.206 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 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. Creates a copy of a given JSON value. 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.","title":"nlohmann::basic_json::basic_json"},{"location":"api/basic_json/basic_json/#template-parameters","text":"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","title":"Template parameters"},{"location":"api/basic_json/basic_json/#parameters","text":"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) begin of the range to copy from (included) last (in) end of the range to copy from (excluded) other (in) the JSON value to copy/move","title":"Parameters"},{"location":"api/basic_json/basic_json/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes to any JSON value. No-throw guarantee: this constructor never throws exceptions. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no to_json() function was provided), strong guarantee holds: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Strong guarantee: if an exception is thrown, there are no changes to any JSON value. No-throw guarantee: this constructor never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/basic_json/#exceptions","text":"(none) The function does not throw exceptions. (none) (none) The function can throw the following exceptions: Throws type_error.301 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. (none) The function can throw the following exceptions: Throws invalid_iterator.201 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 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 example code below. Throws invalid_iterator.206 if iterators first and last belong to a null value. In this case, the range [first, last) is undefined. (none) The function does not throw exceptions.","title":"Exceptions"},{"location":"api/basic_json/basic_json/#complexity","text":"Constant. Constant. Usually linear in the size of the passed val , also depending on the implementation of the called to_json() method. Usually linear in the size of the passed val , also depending on the implementation of the called to_json() method. Linear in the size of the initializer list init . Linear in cnt . Linear in distance between first and last . Linear in the size of other . Constant.","title":"Complexity"},{"location":"api/basic_json/basic_json/#notes","text":"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 . 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 . Overload 8: Postcondition * this == other Overload 9: Postconditions ` * this has the same value as other before the call. other is a JSON null value","title":"Notes"},{"location":"api/basic_json/basic_json/#examples","text":"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 < std :: string , int > c_map { { \"one\" , 1 }, { \"two\" , 2 }, { \"three\" , 3 } }; json j_map ( c_map ); // create an object from std::unordered_map std :: unordered_map < const char * , double > c_umap { { \"one\" , 1.2 }, { \"two\" , 2.3 }, { \"three\" , 3.4 } }; json j_umap ( c_umap ); // create an object from std::multimap std :: multimap < std :: string , bool > 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 < std :: string , bool > 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 < int > c_vector { 1 , 2 , 3 , 4 }; json j_vec ( c_vector ); // create an array from std::valarray std :: valarray < short > c_valarray { 10 , 9 , 8 , 7 }; json j_valarray ( c_valarray ); // create an array from std::deque std :: deque < double > c_deque { 1.2 , 2.3 , 3.4 , 5.6 }; json j_deque ( c_deque ); // create an array from std::list std :: list < bool > c_list { true , true , false , true }; json j_list ( c_list ); // create an array from std::forward_list std :: forward_list < std :: int64_t > c_flist { 12345678909876 , 23456789098765 , 34567890987654 , 45678909876543 }; json j_flist ( c_flist ); // create an array from std::array std :: array < unsigned long , 4 > c_array {{ 1 , 2 , 3 , 4 }}; json j_array ( c_array ); // create an array from std::set std :: set < std :: string > 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 < std :: string > 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 < std :: string > 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 < std :: string > 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 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 ( json :: invalid_iterator & e ) { std :: cout << e . what () << '\\n' ; } } Output: [ \"bravo\" , \"charly\" ] 42 { \"one\" : \"eins\" } [ jso n .excep t io n .i n valid_i terat or. 204 ] i terat ors ou t o f ra n ge 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","title":"Examples"},{"location":"api/basic_json/basic_json/#version-history","text":"Since version 1.0.0. Since version 1.0.0. Since version 2.1.0. Since version 3.2.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0.","title":"Version history"},{"location":"api/basic_json/begin/","text":"nlohmann::basic_json:: begin \u00b6 iterator begin () noexcept ; const_iterator begin () const noexcept ; Returns an iterator to the first element. Return value \u00b6 iterator to the first element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"begin"},{"location":"api/basic_json/begin/#nlohmannbasic_jsonbegin","text":"iterator begin () noexcept ; const_iterator begin () const noexcept ; Returns an iterator to the first element.","title":"nlohmann::basic_json::begin"},{"location":"api/basic_json/begin/#return-value","text":"iterator to the first element","title":"Return value"},{"location":"api/basic_json/begin/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/begin/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/begin/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/begin/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/binary/","text":"nlohmann::basic_json:: binary \u00b6 // (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 ); Creates a JSON binary array value from a given binary container. 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 \u00b6 init (in) container containing bytes to use as binary type subtype (in) subtype to use in CBOR, MessagePack, and BSON Return value \u00b6 JSON binary array value Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the size of init ; constant for typename binary_t::container_type&& init versions. Notes \u00b6 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 \u00b6 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 < std :: uint8_t > 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: t ype : bi nar y , sub t ype : 42 Version history \u00b6 Added in version 3.8.0.","title":"binary"},{"location":"api/basic_json/binary/#nlohmannbasic_jsonbinary","text":"// (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 ); Creates a JSON binary array value from a given binary container. 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.","title":"nlohmann::basic_json::binary"},{"location":"api/basic_json/binary/#parameters","text":"init (in) container containing bytes to use as binary type subtype (in) subtype to use in CBOR, MessagePack, and BSON","title":"Parameters"},{"location":"api/basic_json/binary/#return-value","text":"JSON binary array value","title":"Return value"},{"location":"api/basic_json/binary/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/binary/#complexity","text":"Linear in the size of init ; constant for typename binary_t::container_type&& init versions.","title":"Complexity"},{"location":"api/basic_json/binary/#notes","text":"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.","title":"Notes"},{"location":"api/basic_json/binary/#examples","text":"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 < std :: uint8_t > 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: t ype : bi nar y , sub t ype : 42","title":"Examples"},{"location":"api/basic_json/binary/#version-history","text":"Added in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/binary_t/","text":"nlohmann::basic_json:: binary_t \u00b6 using binary_t = byte_container_with_subtype < BinaryType > ; 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 . CBOR's RFC 7049 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 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 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 < std :: uint8_t > , which is a very common way to represent a byte array in modern C++. Template parameters \u00b6 BinaryType container type to store arrays Notes \u00b6 Default type \u00b6 The default values for BinaryType is std :: vector < std :: uint8_t > . Storage \u00b6 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 \u00b6 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 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 unsigned 8-bit integer. If no subtype is given, the generic binary subtype 0x00 is used. Examples \u00b6 Example The following code shows that binary_t is by default, a typedef to nlohmann :: byte_container_with_subtype < std :: vector < std :: uint8_t >> . #include #include #include using json = nlohmann :: json ; int main () { 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 \u00b6 byte_container_with_subtype Version history \u00b6 Added in version 3.8.0. Changed type of subtype to std::uint64_t in version 3.10.0.","title":"binary_t"},{"location":"api/basic_json/binary_t/#nlohmannbasic_jsonbinary_t","text":"using binary_t = byte_container_with_subtype < BinaryType > ; 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 . CBOR's RFC 7049 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 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 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 < std :: uint8_t > , which is a very common way to represent a byte array in modern C++.","title":"nlohmann::basic_json::binary_t"},{"location":"api/basic_json/binary_t/#template-parameters","text":"BinaryType container type to store arrays","title":"Template parameters"},{"location":"api/basic_json/binary_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/binary_t/#default-type","text":"The default values for BinaryType is std :: vector < std :: uint8_t > .","title":"Default type"},{"location":"api/basic_json/binary_t/#storage","text":"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.","title":"Storage"},{"location":"api/basic_json/binary_t/#notes-on-subtypes","text":"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 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 unsigned 8-bit integer. If no subtype is given, the generic binary subtype 0x00 is used.","title":"Notes on subtypes"},{"location":"api/basic_json/binary_t/#examples","text":"Example The following code shows that binary_t is by default, a typedef to nlohmann :: byte_container_with_subtype < std :: vector < std :: uint8_t >> . #include #include #include using json = nlohmann :: json ; int main () { 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","title":"Examples"},{"location":"api/basic_json/binary_t/#see-also","text":"byte_container_with_subtype","title":"See also"},{"location":"api/basic_json/binary_t/#version-history","text":"Added in version 3.8.0. Changed type of subtype to std::uint64_t in version 3.10.0.","title":"Version history"},{"location":"api/basic_json/boolean_t/","text":"nlohmann::basic_json:: boolean_t \u00b6 using boolean_t = BooleanType ; The type used to store JSON booleans. RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false . To store objects in C++, a type is defined by the template parameter BooleanType which chooses the type to use. Notes \u00b6 Default type \u00b6 With the default values for BooleanType ( bool ), the default value for boolean_t is bool . Storage \u00b6 Boolean values are stored directly inside a basic_json type. Examples \u00b6 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 < bool , json :: boolean_t >:: value << std :: endl ; } Output: true Version history \u00b6 Added in version 1.0.0.","title":"boolean_t"},{"location":"api/basic_json/boolean_t/#nlohmannbasic_jsonboolean_t","text":"using boolean_t = BooleanType ; The type used to store JSON booleans. RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false . To store objects in C++, a type is defined by the template parameter BooleanType which chooses the type to use.","title":"nlohmann::basic_json::boolean_t"},{"location":"api/basic_json/boolean_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/boolean_t/#default-type","text":"With the default values for BooleanType ( bool ), the default value for boolean_t is bool .","title":"Default type"},{"location":"api/basic_json/boolean_t/#storage","text":"Boolean values are stored directly inside a basic_json type.","title":"Storage"},{"location":"api/basic_json/boolean_t/#examples","text":"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 < bool , json :: boolean_t >:: value << std :: endl ; } Output: true","title":"Examples"},{"location":"api/basic_json/boolean_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/cbegin/","text":"nlohmann::basic_json:: cbegin \u00b6 const_iterator cbegin () const noexcept ; Returns an iterator to the first element. Return value \u00b6 iterator to the first element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"cbegin"},{"location":"api/basic_json/cbegin/#nlohmannbasic_jsoncbegin","text":"const_iterator cbegin () const noexcept ; Returns an iterator to the first element.","title":"nlohmann::basic_json::cbegin"},{"location":"api/basic_json/cbegin/#return-value","text":"iterator to the first element","title":"Return value"},{"location":"api/basic_json/cbegin/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/cbegin/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/cbegin/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/cbegin/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/cbor_tag_handler_t/","text":"nlohmann::basic_json:: cbor_tag_handler_t \u00b6 enum class cbor_tag_handler_t { error , ignore , store }; This enumeration is used in the from_cbor 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 \u00b6 Example The example below shows how the different values of the cbor_tag_handler_t influence the behavior of from_cbor when reading a tagged byte string. #include #include using json = nlohmann :: json ; int main () { // tagged byte string std :: vector < std :: uint8_t > 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 ( 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: [ jso n .excep t io n .parse_error. 112 ] parse error a t by te 1 : sy nta x error while parsi n g CBOR value : i n valid by te : 0 xD 8 { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : null } { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : 66 } Version history \u00b6 Added in version 3.9.0. Added value store in 3.10.0.","title":"cbor_tag_handler_t"},{"location":"api/basic_json/cbor_tag_handler_t/#nlohmannbasic_jsoncbor_tag_handler_t","text":"enum class cbor_tag_handler_t { error , ignore , store }; This enumeration is used in the from_cbor 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)","title":"nlohmann::basic_json::cbor_tag_handler_t"},{"location":"api/basic_json/cbor_tag_handler_t/#examples","text":"Example The example below shows how the different values of the cbor_tag_handler_t influence the behavior of from_cbor when reading a tagged byte string. #include #include using json = nlohmann :: json ; int main () { // tagged byte string std :: vector < std :: uint8_t > 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 ( 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: [ jso n .excep t io n .parse_error. 112 ] parse error a t by te 1 : sy nta x error while parsi n g CBOR value : i n valid by te : 0 xD 8 { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : null } { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : 66 }","title":"Examples"},{"location":"api/basic_json/cbor_tag_handler_t/#version-history","text":"Added in version 3.9.0. Added value store in 3.10.0.","title":"Version history"},{"location":"api/basic_json/cend/","text":"nlohmann::basic_json:: cend \u00b6 const_iterator cend () const noexcept ; Returns an iterator to one past the last element. Return value \u00b6 iterator one past the last element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"cend"},{"location":"api/basic_json/cend/#nlohmannbasic_jsoncend","text":"const_iterator cend () const noexcept ; Returns an iterator to one past the last element.","title":"nlohmann::basic_json::cend"},{"location":"api/basic_json/cend/#return-value","text":"iterator one past the last element","title":"Return value"},{"location":"api/basic_json/cend/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/cend/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/cend/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/cend/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/clear/","text":"nlohmann::basic_json:: clear \u00b6 void clear () noexcept ; Clears the content of a JSON value and resets it to the default value as if basic_json(value_t) would have been called with the current value type from type() : 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 \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear in the size of the JSON value. Notes \u00b6 All iterators, pointers and references related to this container are invalidated. Examples \u00b6 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 \u00b6 Added in version 1.0.0. Added support for binary types in version 3.8.0.","title":"clear"},{"location":"api/basic_json/clear/#nlohmannbasic_jsonclear","text":"void clear () noexcept ; Clears the content of a JSON value and resets it to the default value as if basic_json(value_t) would have been called with the current value type from type() : 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 ());","title":"nlohmann::basic_json::clear"},{"location":"api/basic_json/clear/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/clear/#complexity","text":"Linear in the size of the JSON value.","title":"Complexity"},{"location":"api/basic_json/clear/#notes","text":"All iterators, pointers and references related to this container are invalidated.","title":"Notes"},{"location":"api/basic_json/clear/#examples","text":"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 {} [] \"\"","title":"Examples"},{"location":"api/basic_json/clear/#version-history","text":"Added in version 1.0.0. Added support for binary types in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/contains/","text":"nlohmann::basic_json:: contains \u00b6 // (1) bool contains ( const typename object_t :: key_type & key ) const ; // (2) template < typename KeyType > bool contains ( KeyType && key ) const ; // (3) bool contains ( const json_pointer & ptr ) const ; 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. 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. Check whether the given JSON pointer ptr can be resolved in the current JSON value. Template parameters \u00b6 KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17). Parameters \u00b6 key (in) key value to check its existence. ptr (in) JSON pointer to check its existence. Return value \u00b6 true if an element with specified key exists. If no such element with such key is found or the JSON value is not an object, false is returned. See 1. true if the JSON pointer can be resolved to a stored value, false otherwise. Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 The function does not throw exceptions. The function does not throw exceptions. The function can throw the following exceptions: Throws parse_error.106 if an array index begins with 0 . Throws parse_error.109 if an array index was not a number. Complexity \u00b6 Logarithmic in the size of the JSON object. Notes \u00b6 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 \u00b6 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_objec t co nta i ns 'key' : true j_objec t co nta i ns 'a n o t her' : false j_array co nta i ns '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_objec t co nta i ns 'key' : true j_objec t co nta i ns 'a n o t her' : false j_array co nta i ns '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 ( 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 ( json :: parse_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: true true true true false false false Version history \u00b6 Added in version 3.11.0. Added in version 3.6.0. Extended template KeyType to support comparable types in version 3.11.0. Added in version 3.7.0.","title":"contains"},{"location":"api/basic_json/contains/#nlohmannbasic_jsoncontains","text":"// (1) bool contains ( const typename object_t :: key_type & key ) const ; // (2) template < typename KeyType > bool contains ( KeyType && key ) const ; // (3) bool contains ( const json_pointer & ptr ) const ; 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. 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. Check whether the given JSON pointer ptr can be resolved in the current JSON value.","title":"nlohmann::basic_json::contains"},{"location":"api/basic_json/contains/#template-parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17).","title":"Template parameters"},{"location":"api/basic_json/contains/#parameters","text":"key (in) key value to check its existence. ptr (in) JSON pointer to check its existence.","title":"Parameters"},{"location":"api/basic_json/contains/#return-value","text":"true if an element with specified key exists. If no such element with such key is found or the JSON value is not an object, false is returned. See 1. true if the JSON pointer can be resolved to a stored value, false otherwise.","title":"Return value"},{"location":"api/basic_json/contains/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/contains/#exceptions","text":"The function does not throw exceptions. The function does not throw exceptions. The function can throw the following exceptions: Throws parse_error.106 if an array index begins with 0 . Throws parse_error.109 if an array index was not a number.","title":"Exceptions"},{"location":"api/basic_json/contains/#complexity","text":"Logarithmic in the size of the JSON object.","title":"Complexity"},{"location":"api/basic_json/contains/#notes","text":"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] .","title":"Notes"},{"location":"api/basic_json/contains/#examples","text":"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_objec t co nta i ns 'key' : true j_objec t co nta i ns 'a n o t her' : false j_array co nta i ns '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_objec t co nta i ns 'key' : true j_objec t co nta i ns 'a n o t her' : false j_array co nta i ns '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 ( 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 ( json :: parse_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: true true true true false false false","title":"Examples"},{"location":"api/basic_json/contains/#version-history","text":"Added in version 3.11.0. Added in version 3.6.0. Extended template KeyType to support comparable types in version 3.11.0. Added in version 3.7.0.","title":"Version history"},{"location":"api/basic_json/count/","text":"nlohmann::basic_json:: count \u00b6 // (1) size_type count ( const typename object_t :: key_type & key ) const ; // (2) template < typename KeyType > size_type count ( KeyType && key ) const ; 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). 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 \u00b6 KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17). Parameters \u00b6 key (in) key value of the element to count. Return value \u00b6 Number of elements with key key . If the JSON value is not an object, the return value will be 0 . Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Complexity \u00b6 Logarithmic in the size of the JSON object. Notes \u00b6 This method always returns 0 when executed on a JSON type that is not an object. Examples \u00b6 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: nu mber o f eleme nts wi t h key \"two\" : 1 nu mber o f eleme nts wi t h 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: nu mber o f eleme nts wi t h key \"two\" : 1 nu mber o f eleme nts wi t h key \"three\" : 0 Version history \u00b6 Added in version 3.11.0. Added in version 1.0.0. Changed parameter key type to KeyType&& in version 3.11.0.","title":"count"},{"location":"api/basic_json/count/#nlohmannbasic_jsoncount","text":"// (1) size_type count ( const typename object_t :: key_type & key ) const ; // (2) template < typename KeyType > size_type count ( KeyType && key ) const ; 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). 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.","title":"nlohmann::basic_json::count"},{"location":"api/basic_json/count/#template-parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17).","title":"Template parameters"},{"location":"api/basic_json/count/#parameters","text":"key (in) key value of the element to count.","title":"Parameters"},{"location":"api/basic_json/count/#return-value","text":"Number of elements with key key . If the JSON value is not an object, the return value will be 0 .","title":"Return value"},{"location":"api/basic_json/count/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/count/#complexity","text":"Logarithmic in the size of the JSON object.","title":"Complexity"},{"location":"api/basic_json/count/#notes","text":"This method always returns 0 when executed on a JSON type that is not an object.","title":"Notes"},{"location":"api/basic_json/count/#examples","text":"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: nu mber o f eleme nts wi t h key \"two\" : 1 nu mber o f eleme nts wi t h 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: nu mber o f eleme nts wi t h key \"two\" : 1 nu mber o f eleme nts wi t h key \"three\" : 0","title":"Examples"},{"location":"api/basic_json/count/#version-history","text":"Added in version 3.11.0. Added in version 1.0.0. Changed parameter key type to KeyType&& in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/crbegin/","text":"nlohmann::basic_json:: crbegin \u00b6 const_reverse_iterator crbegin () const noexcept ; Returns an iterator to the reverse-beginning; that is, the last element. Return value \u00b6 reverse iterator to the first element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"crbegin"},{"location":"api/basic_json/crbegin/#nlohmannbasic_jsoncrbegin","text":"const_reverse_iterator crbegin () const noexcept ; Returns an iterator to the reverse-beginning; that is, the last element.","title":"nlohmann::basic_json::crbegin"},{"location":"api/basic_json/crbegin/#return-value","text":"reverse iterator to the first element","title":"Return value"},{"location":"api/basic_json/crbegin/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/crbegin/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/crbegin/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/crbegin/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/crend/","text":"nlohmann::basic_json:: crend \u00b6 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 \u00b6 reverse iterator to the element following the last element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 Example The following code shows an example for eend() . #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 \u00b6 Added in version 1.0.0.","title":"crend"},{"location":"api/basic_json/crend/#nlohmannbasic_jsoncrend","text":"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.","title":"nlohmann::basic_json::crend"},{"location":"api/basic_json/crend/#return-value","text":"reverse iterator to the element following the last element","title":"Return value"},{"location":"api/basic_json/crend/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/crend/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/crend/#examples","text":"Example The following code shows an example for eend() . #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","title":"Examples"},{"location":"api/basic_json/crend/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/default_object_comparator_t/","text":"nlohmann::basic_json:: default_object_comparator_t \u00b6 using default_object_comparator_t = std :: less < StringType > ; // until C++14 using default_object_comparator_t = std :: less <> ; // since C++14 The default comparator used by object_t . 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 and can be obtained via object_comparator_t . Examples \u00b6 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: o ne < t wo : true t hree < f our : false Version history \u00b6 Added in version 3.11.0.","title":"default_object_comparator_t"},{"location":"api/basic_json/default_object_comparator_t/#nlohmannbasic_jsondefault_object_comparator_t","text":"using default_object_comparator_t = std :: less < StringType > ; // until C++14 using default_object_comparator_t = std :: less <> ; // since C++14 The default comparator used by object_t . 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 and can be obtained via object_comparator_t .","title":"nlohmann::basic_json::default_object_comparator_t"},{"location":"api/basic_json/default_object_comparator_t/#examples","text":"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: o ne < t wo : true t hree < f our : false","title":"Examples"},{"location":"api/basic_json/default_object_comparator_t/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/diff/","text":"nlohmann::basic_json:: diff \u00b6 static basic_json diff ( const basic_json & source , const basic_json & target ); Creates a JSON Patch so that value source can be changed into the value target by calling patch function. For two JSON values source and target , the following code yields always true : source . patch ( diff ( source , target )) == target ; Parameters \u00b6 source (in) JSON value to compare from target (in) JSON value to compare against Return value \u00b6 a JSON patch to convert the source to target Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the lengths of source and target . Notes \u00b6 Currently, only remove , add , and replace operations are generated. Examples \u00b6 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 \u00b6 RFC 6902 (JSON Patch) Version history \u00b6 Added in version 2.0.0.","title":"diff"},{"location":"api/basic_json/diff/#nlohmannbasic_jsondiff","text":"static basic_json diff ( const basic_json & source , const basic_json & target ); Creates a JSON Patch so that value source can be changed into the value target by calling patch function. For two JSON values source and target , the following code yields always true : source . patch ( diff ( source , target )) == target ;","title":"nlohmann::basic_json::diff"},{"location":"api/basic_json/diff/#parameters","text":"source (in) JSON value to compare from target (in) JSON value to compare against","title":"Parameters"},{"location":"api/basic_json/diff/#return-value","text":"a JSON patch to convert the source to target","title":"Return value"},{"location":"api/basic_json/diff/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/diff/#complexity","text":"Linear in the lengths of source and target .","title":"Complexity"},{"location":"api/basic_json/diff/#notes","text":"Currently, only remove , add , and replace operations are generated.","title":"Notes"},{"location":"api/basic_json/diff/#examples","text":"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\" ] }","title":"Examples"},{"location":"api/basic_json/diff/#see-also","text":"RFC 6902 (JSON Patch)","title":"See also"},{"location":"api/basic_json/diff/#version-history","text":"Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/dump/","text":"nlohmann::basic_json:: dump \u00b6 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 , and currently supports its indent and ensure_ascii parameters. Parameters \u00b6 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 : strict (throws and 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 bytes are copied to the output unchanged)). Return value \u00b6 string containing the serialization of the JSON value Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Exceptions \u00b6 Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded and error_handler is set to strict Complexity \u00b6 Linear. Notes \u00b6 Binary values are serialized as 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 \u00b6 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\u00f6 \ud83d\ude00!\" ; // 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 = \"\u00e4 \\xA9 \u00fc\" ; try { std :: cout << j_invalid . dump () << std :: endl ; } catch ( 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 ) << \" \\n string with ignored invalid characters: \" << j_invalid . dump ( -1 , ' ' , false , json :: error_handler_t :: ignore ) << '\\n' ; } Output: objec ts : { \"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 ] s tr i n gs : \"Hell\u00f6 \ud83d\ude00!\" \"Hell\\u00f6 \\ud83d\\ude00!\" [ jso n .excep t io n . t ype_error. 316 ] i n valid UTF -8 by te a t i n dex 2 : 0 xA 9 s tr i n g wi t h replaced i n valid charac ters : \"\u00e4\ufffd\u00fc\" s tr i n g wi t h ig n ored i n valid charac ters : \"\u00e4\u00fc\" Version history \u00b6 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.","title":"dump"},{"location":"api/basic_json/dump/#nlohmannbasic_jsondump","text":"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 , and currently supports its indent and ensure_ascii parameters.","title":"nlohmann::basic_json::dump"},{"location":"api/basic_json/dump/#parameters","text":"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 : strict (throws and 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 bytes are copied to the output unchanged)).","title":"Parameters"},{"location":"api/basic_json/dump/#return-value","text":"string containing the serialization of the JSON value","title":"Return value"},{"location":"api/basic_json/dump/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes to any JSON value.","title":"Exception safety"},{"location":"api/basic_json/dump/#exceptions","text":"Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded and error_handler is set to strict","title":"Exceptions"},{"location":"api/basic_json/dump/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/dump/#notes","text":"Binary values are serialized as object containing two keys: \"bytes\": an array of bytes as integers \"subtype\": the subtype as integer or null if the binary has no subtype","title":"Notes"},{"location":"api/basic_json/dump/#examples","text":"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\u00f6 \ud83d\ude00!\" ; // 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 = \"\u00e4 \\xA9 \u00fc\" ; try { std :: cout << j_invalid . dump () << std :: endl ; } catch ( 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 ) << \" \\n string with ignored invalid characters: \" << j_invalid . dump ( -1 , ' ' , false , json :: error_handler_t :: ignore ) << '\\n' ; } Output: objec ts : { \"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 ] s tr i n gs : \"Hell\u00f6 \ud83d\ude00!\" \"Hell\\u00f6 \\ud83d\\ude00!\" [ jso n .excep t io n . t ype_error. 316 ] i n valid UTF -8 by te a t i n dex 2 : 0 xA 9 s tr i n g wi t h replaced i n valid charac ters : \"\u00e4\ufffd\u00fc\" s tr i n g wi t h ig n ored i n valid charac ters : \"\u00e4\u00fc\"","title":"Examples"},{"location":"api/basic_json/dump/#version-history","text":"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.","title":"Version history"},{"location":"api/basic_json/emplace/","text":"nlohmann::basic_json:: emplace \u00b6 template < class ... Args > std :: pair < iterator , bool > 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 \u00b6 Args compatible types to create a basic_json object Parameters \u00b6 args (in) arguments to forward to a constructor of basic_json Return value \u00b6 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. Exceptions \u00b6 Throws type_error.311 when called on a type other than JSON object or null ; example: \"cannot use emplace() with number\" Complexity \u00b6 Logarithmic in the size of the container, O(log( size() )). Examples \u00b6 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 Version history \u00b6 Since version 2.0.8.","title":"emplace"},{"location":"api/basic_json/emplace/#nlohmannbasic_jsonemplace","text":"template < class ... Args > std :: pair < iterator , bool > 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 .","title":"nlohmann::basic_json::emplace"},{"location":"api/basic_json/emplace/#template-parameters","text":"Args compatible types to create a basic_json object","title":"Template parameters"},{"location":"api/basic_json/emplace/#parameters","text":"args (in) arguments to forward to a constructor of basic_json","title":"Parameters"},{"location":"api/basic_json/emplace/#return-value","text":"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.","title":"Return value"},{"location":"api/basic_json/emplace/#exceptions","text":"Throws type_error.311 when called on a type other than JSON object or null ; example: \"cannot use emplace() with number\"","title":"Exceptions"},{"location":"api/basic_json/emplace/#complexity","text":"Logarithmic in the size of the container, O(log( size() )).","title":"Complexity"},{"location":"api/basic_json/emplace/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/emplace/#version-history","text":"Since version 2.0.8.","title":"Version history"},{"location":"api/basic_json/emplace_back/","text":"nlohmann::basic_json:: emplace_back \u00b6 template < class ... Args > 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 \u00b6 Args compatible types to create a basic_json object Parameters \u00b6 args (in) arguments to forward to a constructor of basic_json Return value \u00b6 reference to the inserted element Exceptions \u00b6 Throws type_error.311 when called on a type other than JSON array or null ; example: \"cannot use emplace_back() with number\" Complexity \u00b6 Amortized constant. Examples \u00b6 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\" ]] Version history \u00b6 Since version 2.0.8. Returns reference since 3.7.0.","title":"emplace_back"},{"location":"api/basic_json/emplace_back/#nlohmannbasic_jsonemplace_back","text":"template < class ... Args > 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 .","title":"nlohmann::basic_json::emplace_back"},{"location":"api/basic_json/emplace_back/#template-parameters","text":"Args compatible types to create a basic_json object","title":"Template parameters"},{"location":"api/basic_json/emplace_back/#parameters","text":"args (in) arguments to forward to a constructor of basic_json","title":"Parameters"},{"location":"api/basic_json/emplace_back/#return-value","text":"reference to the inserted element","title":"Return value"},{"location":"api/basic_json/emplace_back/#exceptions","text":"Throws type_error.311 when called on a type other than JSON array or null ; example: \"cannot use emplace_back() with number\"","title":"Exceptions"},{"location":"api/basic_json/emplace_back/#complexity","text":"Amortized constant.","title":"Complexity"},{"location":"api/basic_json/emplace_back/#examples","text":"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\" ]]","title":"Examples"},{"location":"api/basic_json/emplace_back/#version-history","text":"Since version 2.0.8. Returns reference since 3.7.0.","title":"Version history"},{"location":"api/basic_json/empty/","text":"nlohmann::basic_json:: empty \u00b6 bool empty () const noexcept ; Checks if a JSON value has no elements (i.e. whether its size() is 0 ). Return value \u00b6 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 \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant, as long as array_t and object_t satisfy the Container concept; that is, their empty() functions have constant complexity. Possible implementation \u00b6 bool empty () const noexcept { return size () == 0 ; } Notes \u00b6 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 \u00b6 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 \u00b6 Added in version 1.0.0. Extended to return false for binary types in version 3.8.0.","title":"empty"},{"location":"api/basic_json/empty/#nlohmannbasic_jsonempty","text":"bool empty () const noexcept ; Checks if a JSON value has no elements (i.e. whether its size() is 0 ).","title":"nlohmann::basic_json::empty"},{"location":"api/basic_json/empty/#return-value","text":"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()","title":"Return value"},{"location":"api/basic_json/empty/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/empty/#complexity","text":"Constant, as long as array_t and object_t satisfy the Container concept; that is, their empty() functions have constant complexity.","title":"Complexity"},{"location":"api/basic_json/empty/#possible-implementation","text":"bool empty () const noexcept { return size () == 0 ; }","title":"Possible implementation"},{"location":"api/basic_json/empty/#notes","text":"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.","title":"Notes"},{"location":"api/basic_json/empty/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/empty/#version-history","text":"Added in version 1.0.0. Extended to return false for binary types in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/end/","text":"nlohmann::basic_json:: end \u00b6 iterator end () noexcept ; const_iterator end () const noexcept ; Returns an iterator to one past the last element. Return value \u00b6 iterator one past the last element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"end"},{"location":"api/basic_json/end/#nlohmannbasic_jsonend","text":"iterator end () noexcept ; const_iterator end () const noexcept ; Returns an iterator to one past the last element.","title":"nlohmann::basic_json::end"},{"location":"api/basic_json/end/#return-value","text":"iterator one past the last element","title":"Return value"},{"location":"api/basic_json/end/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/end/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/end/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/end/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/erase/","text":"nlohmann::basic_json:: erase \u00b6 // (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 < typename KeyType > size_type erase ( KeyType && key ); // (5) void erase ( const size_type idx ); 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 . 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 . Removes an element from a JSON object by key. 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. Removes an element from a JSON array by index. Template parameters \u00b6 KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17). Parameters \u00b6 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 \u00b6 Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned. Iterator following the last removed element. If the iterator last refers to the last element, the end() iterator is returned. 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). See 3. (none) Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 The function can throw the following exceptions: Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\" Throws invalid_iterator.202 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 if called on a primitive type with invalid iterator (i.e., any iterator which is not begin() ); example: \"iterator out of range\" The function can throw the following exceptions: Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\" Throws invalid_iterator.203 if called on iterators which does not belong to the current JSON value; example: \"iterators do not fit current value\" Throws invalid_iterator.204 if called on a primitive type with invalid iterators (i.e., if first != begin() and last != end() ); example: \"iterators out of range\" The function can throw the following exceptions: Throws type_error.307 when called on a type other than JSON object; example: \"cannot use erase() with null\" See 3. The function can throw the following exceptions: Throws type_error.307 when called on a type other than JSON object; example: \"cannot use erase() with null\" Throws out_of_range.401 when idx >= size() ; example: \"array index 17 is out of range\" Complexity \u00b6 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 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 log(size()) + count(key) log(size()) + count(key) Linear in distance between idx and the end of the container. Notes \u00b6 Invalidates iterators and references at or after the point of the erase , including the end() iterator. (none) References and iterators to the erased elements are invalidated. Other references and iterators are not affected. See 3. (none) Examples \u00b6 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 ] Version history \u00b6 Added in version 1.0.0. Added support for binary types in version 3.8.0. Added in version 1.0.0. Added support for binary types in version 3.8.0. Added in version 1.0.0. Added in version 3.11.0. Added in version 1.0.0.","title":"erase"},{"location":"api/basic_json/erase/#nlohmannbasic_jsonerase","text":"// (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 < typename KeyType > size_type erase ( KeyType && key ); // (5) void erase ( const size_type idx ); 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 . 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 . Removes an element from a JSON object by key. 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. Removes an element from a JSON array by index.","title":"nlohmann::basic_json::erase"},{"location":"api/basic_json/erase/#template-parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17).","title":"Template parameters"},{"location":"api/basic_json/erase/#parameters","text":"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","title":"Parameters"},{"location":"api/basic_json/erase/#return-value","text":"Iterator following the last removed element. If the iterator pos refers to the last element, the end() iterator is returned. Iterator following the last removed element. If the iterator last refers to the last element, the end() iterator is returned. 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). See 3. (none)","title":"Return value"},{"location":"api/basic_json/erase/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/erase/#exceptions","text":"The function can throw the following exceptions: Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\" Throws invalid_iterator.202 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 if called on a primitive type with invalid iterator (i.e., any iterator which is not begin() ); example: \"iterator out of range\" The function can throw the following exceptions: Throws type_error.307 if called on a null value; example: \"cannot use erase() with null\" Throws invalid_iterator.203 if called on iterators which does not belong to the current JSON value; example: \"iterators do not fit current value\" Throws invalid_iterator.204 if called on a primitive type with invalid iterators (i.e., if first != begin() and last != end() ); example: \"iterators out of range\" The function can throw the following exceptions: Throws type_error.307 when called on a type other than JSON object; example: \"cannot use erase() with null\" See 3. The function can throw the following exceptions: Throws type_error.307 when called on a type other than JSON object; example: \"cannot use erase() with null\" Throws out_of_range.401 when idx >= size() ; example: \"array index 17 is out of range\"","title":"Exceptions"},{"location":"api/basic_json/erase/#complexity","text":"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 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 log(size()) + count(key) log(size()) + count(key) Linear in distance between idx and the end of the container.","title":"Complexity"},{"location":"api/basic_json/erase/#notes","text":"Invalidates iterators and references at or after the point of the erase , including the end() iterator. (none) References and iterators to the erased elements are invalidated. Other references and iterators are not affected. See 3. (none)","title":"Notes"},{"location":"api/basic_json/erase/#examples","text":"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 ]","title":"Examples"},{"location":"api/basic_json/erase/#version-history","text":"Added in version 1.0.0. Added support for binary types in version 3.8.0. Added in version 1.0.0. Added support for binary types in version 3.8.0. Added in version 1.0.0. Added in version 3.11.0. Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/error_handler_t/","text":"nlohmann::basic_json:: error_handler_t \u00b6 enum class error_handler_t { strict , replace , ignore }; This enumeration is used in the dump 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 (\ufffd REPLACEMENT CHARACTER) ignore ignore invalid UTF-8 sequences; all bytes are copied to the output unchanged Examples \u00b6 Example The example below shows how the different values of the error_handler_t influence the behavior of dump 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 = \"\u00e4 \\xA9 \u00fc\" ; try { std :: cout << j_invalid . dump () << std :: endl ; } catch ( 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 ) << \" \\n string with ignored invalid characters: \" << j_invalid . dump ( -1 , ' ' , false , json :: error_handler_t :: ignore ) << '\\n' ; } Output: [ jso n .excep t io n . t ype_error. 316 ] i n valid UTF -8 by te a t i n dex 2 : 0 xA 9 s tr i n g wi t h replaced i n valid charac ters : \"\u00e4\ufffd\u00fc\" s tr i n g wi t h ig n ored i n valid charac ters : \"\u00e4\u00fc\" Version history \u00b6 Added in version 3.4.0.","title":"error_handler_t"},{"location":"api/basic_json/error_handler_t/#nlohmannbasic_jsonerror_handler_t","text":"enum class error_handler_t { strict , replace , ignore }; This enumeration is used in the dump 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 (\ufffd REPLACEMENT CHARACTER) ignore ignore invalid UTF-8 sequences; all bytes are copied to the output unchanged","title":"nlohmann::basic_json::error_handler_t"},{"location":"api/basic_json/error_handler_t/#examples","text":"Example The example below shows how the different values of the error_handler_t influence the behavior of dump 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 = \"\u00e4 \\xA9 \u00fc\" ; try { std :: cout << j_invalid . dump () << std :: endl ; } catch ( 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 ) << \" \\n string with ignored invalid characters: \" << j_invalid . dump ( -1 , ' ' , false , json :: error_handler_t :: ignore ) << '\\n' ; } Output: [ jso n .excep t io n . t ype_error. 316 ] i n valid UTF -8 by te a t i n dex 2 : 0 xA 9 s tr i n g wi t h replaced i n valid charac ters : \"\u00e4\ufffd\u00fc\" s tr i n g wi t h ig n ored i n valid charac ters : \"\u00e4\u00fc\"","title":"Examples"},{"location":"api/basic_json/error_handler_t/#version-history","text":"Added in version 3.4.0.","title":"Version history"},{"location":"api/basic_json/exception/","text":"nlohmann::basic_json:: exception \u00b6 class exception : public std :: exception ; This class is an extension of std::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. Subclasses: parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors Member functions \u00b6 what - returns explanatory string Member variables \u00b6 id - the id of the exception Notes \u00b6 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 \u00b6 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 ( json :: exception & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' n o n -e xis t i n g' n o t f ou n d excep t io n id : 403 See also \u00b6 List of exceptions Version history \u00b6 Since version 3.0.0.","title":"exception"},{"location":"api/basic_json/exception/#nlohmannbasic_jsonexception","text":"class exception : public std :: exception ; This class is an extension of std::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. Subclasses: parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors","title":"nlohmann::basic_json::exception"},{"location":"api/basic_json/exception/#member-functions","text":"what - returns explanatory string","title":"Member functions"},{"location":"api/basic_json/exception/#member-variables","text":"id - the id of the exception","title":"Member variables"},{"location":"api/basic_json/exception/#notes","text":"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.","title":"Notes"},{"location":"api/basic_json/exception/#examples","text":"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 ( json :: exception & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key ' n o n -e xis t i n g' n o t f ou n d excep t io n id : 403","title":"Examples"},{"location":"api/basic_json/exception/#see-also","text":"List of exceptions","title":"See also"},{"location":"api/basic_json/exception/#version-history","text":"Since version 3.0.0.","title":"Version history"},{"location":"api/basic_json/find/","text":"nlohmann::basic_json:: find \u00b6 // (1) iterator find ( const typename object_t :: key_type & key ); const_iterator find ( const typename object_t :: key_type & key ) const ; // (2) template < typename KeyType > iterator find ( KeyType && key ); template < typename KeyType > const_iterator find ( KeyType && key ) const ; 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. 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 \u00b6 KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17). Parameters \u00b6 key (in) key value of the element to search for. Return value \u00b6 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 \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Complexity \u00b6 Logarithmic in the size of the JSON object. Notes \u00b6 This method always returns end() when executed on a JSON type that is not an object. Examples \u00b6 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 f ou n d : true value a t key \"two\" : 2 \"three\" was f ou n d : 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 f ou n d : true value a t key \"two\" : 2 \"three\" was f ou n d : false See also \u00b6 contains checks whether a key exists Version history \u00b6 Added in version 3.11.0. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.","title":"find"},{"location":"api/basic_json/find/#nlohmannbasic_jsonfind","text":"// (1) iterator find ( const typename object_t :: key_type & key ); const_iterator find ( const typename object_t :: key_type & key ) const ; // (2) template < typename KeyType > iterator find ( KeyType && key ); template < typename KeyType > const_iterator find ( KeyType && key ) const ; 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. 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.","title":"nlohmann::basic_json::find"},{"location":"api/basic_json/find/#template-parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17).","title":"Template parameters"},{"location":"api/basic_json/find/#parameters","text":"key (in) key value of the element to search for.","title":"Parameters"},{"location":"api/basic_json/find/#return-value","text":"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.","title":"Return value"},{"location":"api/basic_json/find/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/find/#complexity","text":"Logarithmic in the size of the JSON object.","title":"Complexity"},{"location":"api/basic_json/find/#notes","text":"This method always returns end() when executed on a JSON type that is not an object.","title":"Notes"},{"location":"api/basic_json/find/#examples","text":"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 f ou n d : true value a t key \"two\" : 2 \"three\" was f ou n d : 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 f ou n d : true value a t key \"two\" : 2 \"three\" was f ou n d : false","title":"Examples"},{"location":"api/basic_json/find/#see-also","text":"contains checks whether a key exists","title":"See also"},{"location":"api/basic_json/find/#version-history","text":"Added in version 3.11.0. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/flatten/","text":"nlohmann::basic_json:: flatten \u00b6 basic_json flatten () const ; The function creates a JSON object whose keys are JSON pointers (see RFC 6901 ) and whose values are all primitive (see is_primitive() for more information). The original JSON value can be restored using the unflatten() function. Return value \u00b6 an object that maps JSON pointers to primitive values Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Complexity \u00b6 Linear in the size the JSON value. Notes \u00b6 Empty objects and arrays are flattened to null and will not be reconstructed correctly by the unflatten() function. Examples \u00b6 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 \u00b6 unflatten the reverse function Version history \u00b6 Added in version 2.0.0.","title":"flatten"},{"location":"api/basic_json/flatten/#nlohmannbasic_jsonflatten","text":"basic_json flatten () const ; The function creates a JSON object whose keys are JSON pointers (see RFC 6901 ) and whose values are all primitive (see is_primitive() for more information). The original JSON value can be restored using the unflatten() function.","title":"nlohmann::basic_json::flatten"},{"location":"api/basic_json/flatten/#return-value","text":"an object that maps JSON pointers to primitive values","title":"Return value"},{"location":"api/basic_json/flatten/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/flatten/#complexity","text":"Linear in the size the JSON value.","title":"Complexity"},{"location":"api/basic_json/flatten/#notes","text":"Empty objects and arrays are flattened to null and will not be reconstructed correctly by the unflatten() function.","title":"Notes"},{"location":"api/basic_json/flatten/#examples","text":"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 }","title":"Examples"},{"location":"api/basic_json/flatten/#see-also","text":"unflatten the reverse function","title":"See also"},{"location":"api/basic_json/flatten/#version-history","text":"Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/from_bjdata/","text":"nlohmann::basic_json:: from_bjdata \u00b6 // (1) template < typename InputType > static basic_json from_bjdata ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page . Template parameters \u00b6 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 \u00b6 i (in) an input in BJData format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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 \u00b6 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 . Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if a parse error occurs Throws parse_error.113 if a string could not be parsed successfully Complexity \u00b6 Linear in the size of the input. Examples \u00b6 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 < std :: uint8_t > 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 } Version history \u00b6 Added in version 3.11.0.","title":"from_bjdata"},{"location":"api/basic_json/from_bjdata/#nlohmannbasic_jsonfrom_bjdata","text":"// (1) template < typename InputType > static basic_json from_bjdata ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::from_bjdata"},{"location":"api/basic_json/from_bjdata/#template-parameters","text":"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","title":"Template parameters"},{"location":"api/basic_json/from_bjdata/#parameters","text":"i (in) an input in BJData format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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)","title":"Parameters"},{"location":"api/basic_json/from_bjdata/#return-value","text":"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 .","title":"Return value"},{"location":"api/basic_json/from_bjdata/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/from_bjdata/#exceptions","text":"Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if a parse error occurs Throws parse_error.113 if a string could not be parsed successfully","title":"Exceptions"},{"location":"api/basic_json/from_bjdata/#complexity","text":"Linear in the size of the input.","title":"Complexity"},{"location":"api/basic_json/from_bjdata/#examples","text":"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 < std :: uint8_t > 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 }","title":"Examples"},{"location":"api/basic_json/from_bjdata/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/from_bson/","text":"nlohmann::basic_json:: from_bson \u00b6 // (1) template < typename InputType > static basic_json from_bson ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page . Template parameters \u00b6 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 \u00b6 i (in) an input in BSON format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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 \u00b6 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 . Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws parse_error.114 if an unsupported BSON record type is encountered. Complexity \u00b6 Linear in the size of the input. Examples \u00b6 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 < std :: uint8_t > 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 \u00b6 BSON specification to_bson for the analogous serialization from_cbor for the related CBOR format from_msgpack for the related MessagePack format from_ubjson for the related UBJSON format Version history \u00b6 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.","title":"from_bson"},{"location":"api/basic_json/from_bson/#nlohmannbasic_jsonfrom_bson","text":"// (1) template < typename InputType > static basic_json from_bson ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::from_bson"},{"location":"api/basic_json/from_bson/#template-parameters","text":"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","title":"Template parameters"},{"location":"api/basic_json/from_bson/#parameters","text":"i (in) an input in BSON format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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)","title":"Parameters"},{"location":"api/basic_json/from_bson/#return-value","text":"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 .","title":"Return value"},{"location":"api/basic_json/from_bson/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/from_bson/#exceptions","text":"Throws parse_error.114 if an unsupported BSON record type is encountered.","title":"Exceptions"},{"location":"api/basic_json/from_bson/#complexity","text":"Linear in the size of the input.","title":"Complexity"},{"location":"api/basic_json/from_bson/#examples","text":"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 < std :: uint8_t > 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 }","title":"Examples"},{"location":"api/basic_json/from_bson/#see-also","text":"BSON specification to_bson for the analogous serialization from_cbor for the related CBOR format from_msgpack for the related MessagePack format from_ubjson for the related UBJSON format","title":"See also"},{"location":"api/basic_json/from_bson/#version-history","text":"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.","title":"Version history"},{"location":"api/basic_json/from_cbor/","text":"nlohmann::basic_json:: from_cbor \u00b6 // (1) template < typename InputType > 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 < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page . Template parameters \u00b6 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 \u00b6 i (in) an input in CBOR format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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 for more information Return value \u00b6 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 . Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if unsupported features from CBOR were used in the given input or if the input is not valid CBOR Throws parse_error.113 if a string was expected as map key, but not found Complexity \u00b6 Linear in the size of the input. Examples \u00b6 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 < std :: uint8_t > 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 } Version history \u00b6 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.","title":"from_cbor"},{"location":"api/basic_json/from_cbor/#nlohmannbasic_jsonfrom_cbor","text":"// (1) template < typename InputType > 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 < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::from_cbor"},{"location":"api/basic_json/from_cbor/#template-parameters","text":"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","title":"Template parameters"},{"location":"api/basic_json/from_cbor/#parameters","text":"i (in) an input in CBOR format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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 for more information","title":"Parameters"},{"location":"api/basic_json/from_cbor/#return-value","text":"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 .","title":"Return value"},{"location":"api/basic_json/from_cbor/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/from_cbor/#exceptions","text":"Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if unsupported features from CBOR were used in the given input or if the input is not valid CBOR Throws parse_error.113 if a string was expected as map key, but not found","title":"Exceptions"},{"location":"api/basic_json/from_cbor/#complexity","text":"Linear in the size of the input.","title":"Complexity"},{"location":"api/basic_json/from_cbor/#examples","text":"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 < std :: uint8_t > 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 }","title":"Examples"},{"location":"api/basic_json/from_cbor/#version-history","text":"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.","title":"Version history"},{"location":"api/basic_json/from_msgpack/","text":"nlohmann::basic_json:: from_msgpack \u00b6 // (1) template < typename InputType > static basic_json from_msgpack ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page . Template parameters \u00b6 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 \u00b6 i (in) an input in MessagePack format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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 \u00b6 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 . Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if unsupported features from MessagePack were used in the given input or if the input is not valid MessagePack Throws parse_error.113 if a string was expected as map key, but not found Complexity \u00b6 Linear in the size of the input. Examples \u00b6 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 < std :: uint8_t > 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 } Version history \u00b6 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_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_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.","title":"from_msgpack"},{"location":"api/basic_json/from_msgpack/#nlohmannbasic_jsonfrom_msgpack","text":"// (1) template < typename InputType > static basic_json from_msgpack ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::from_msgpack"},{"location":"api/basic_json/from_msgpack/#template-parameters","text":"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","title":"Template parameters"},{"location":"api/basic_json/from_msgpack/#parameters","text":"i (in) an input in MessagePack format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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)","title":"Parameters"},{"location":"api/basic_json/from_msgpack/#return-value","text":"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 .","title":"Return value"},{"location":"api/basic_json/from_msgpack/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/from_msgpack/#exceptions","text":"Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if unsupported features from MessagePack were used in the given input or if the input is not valid MessagePack Throws parse_error.113 if a string was expected as map key, but not found","title":"Exceptions"},{"location":"api/basic_json/from_msgpack/#complexity","text":"Linear in the size of the input.","title":"Complexity"},{"location":"api/basic_json/from_msgpack/#examples","text":"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 < std :: uint8_t > 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 }","title":"Examples"},{"location":"api/basic_json/from_msgpack/#version-history","text":"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_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_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.","title":"Version history"},{"location":"api/basic_json/from_ubjson/","text":"nlohmann::basic_json:: from_ubjson \u00b6 // (1) template < typename InputType > static basic_json from_ubjson ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page . Template parameters \u00b6 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 \u00b6 i (in) an input in UBJSON format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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 \u00b6 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 . Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if a parse error occurs Throws parse_error.113 if a string could not be parsed successfully Complexity \u00b6 Linear in the size of the input. Examples \u00b6 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 < std :: uint8_t > 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 } Version history \u00b6 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.","title":"from_ubjson"},{"location":"api/basic_json/from_ubjson/#nlohmannbasic_jsonfrom_ubjson","text":"// (1) template < typename InputType > static basic_json from_ubjson ( InputType && i , const bool strict = true , const bool allow_exceptions = true ); // (2) template < typename IteratorType > 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. Reads from a compatible input. Reads from an iterator range. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::from_ubjson"},{"location":"api/basic_json/from_ubjson/#template-parameters","text":"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","title":"Template parameters"},{"location":"api/basic_json/from_ubjson/#parameters","text":"i (in) an input in UBJSON format convertible to an input adapter first (in) iterator to start of the input last (in) iterator to 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)","title":"Parameters"},{"location":"api/basic_json/from_ubjson/#return-value","text":"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 .","title":"Return value"},{"location":"api/basic_json/from_ubjson/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/from_ubjson/#exceptions","text":"Throws parse_error.110 if the given input ends prematurely or the end of file was not reached when strict was set to true Throws parse_error.112 if a parse error occurs Throws parse_error.113 if a string could not be parsed successfully","title":"Exceptions"},{"location":"api/basic_json/from_ubjson/#complexity","text":"Linear in the size of the input.","title":"Complexity"},{"location":"api/basic_json/from_ubjson/#examples","text":"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 < std :: uint8_t > 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 }","title":"Examples"},{"location":"api/basic_json/from_ubjson/#version-history","text":"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.","title":"Version history"},{"location":"api/basic_json/front/","text":"nlohmann::basic_json:: front \u00b6 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 \u00b6 In case of a structured type (array or object), a reference to the first element is returned. In case of number, string, boolean, or binary values, a reference to the value is returned. Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 If the JSON value is null , exception invalid_iterator.214 is thrown. Complexity \u00b6 Constant. Notes \u00b6 Precondition The array or object must not be empty. Calling front on an empty array or object yields undefined behavior. Examples \u00b6 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 \u00b6 back to access the last element Version history \u00b6 Added in version 1.0.0. Adjusted code to return reference to binary values in version 3.8.0.","title":"front"},{"location":"api/basic_json/front/#nlohmannbasic_jsonfront","text":"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 () .","title":"nlohmann::basic_json::front"},{"location":"api/basic_json/front/#return-value","text":"In case of a structured type (array or object), a reference to the first element is returned. In case of number, string, boolean, or binary values, a reference to the value is returned.","title":"Return value"},{"location":"api/basic_json/front/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/front/#exceptions","text":"If the JSON value is null , exception invalid_iterator.214 is thrown.","title":"Exceptions"},{"location":"api/basic_json/front/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/front/#notes","text":"Precondition The array or object must not be empty. Calling front on an empty array or object yields undefined behavior.","title":"Notes"},{"location":"api/basic_json/front/#examples","text":"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\"","title":"Examples"},{"location":"api/basic_json/front/#see-also","text":"back to access the last element","title":"See also"},{"location":"api/basic_json/front/#version-history","text":"Added in version 1.0.0. Adjusted code to return reference to binary values in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/get/","text":"nlohmann::basic_json:: get \u00b6 // (1) template < typename ValueType > ValueType get () const noexcept ( noexcept ( JSONSerializer < ValueType >:: from_json ( std :: declval < const basic_json_t &> (), std :: declval < ValueType &> ()))); // (2) template < typename BasicJsonType > BasicJsonType get () const ; // (3) template < typename PointerType > PointerType get_ptr (); template < typename PointerType > constexpr const PointerType get_ptr () const noexcept ; Explicit type conversion between the JSON value and a compatible value which is CopyConstructible and DefaultConstructible . The value is converted by calling the json_serializer from_json() method. The function is equivalent to executing ValueType ret ; JSONSerializer < ValueType >:: 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 and not DefaultConstructible , the value is converted by calling the json_serializer from_json() method. The function is then equivalent to executing return JSONSerializer < ValueTypeCV >:: 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. Overload for basic_json specializations. The function is equivalent to executing return * this ; Explicit pointer access to the internally stored JSON value. No copies are made. Template parameters \u00b6 ValueType the value type to return BasicJsonType a specialization of basic_json PointerType pointer type; must be a pointer to array_t , object_t , string_t , boolean_t , number_integer_t , or number_unsigned_t , number_float_t , or binary_t . Other types will not compile. Return value \u00b6 copy of the JSON value, converted to ValueType a copy of * this , converted into BasicJsonType pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise Exceptions \u00b6 Depends on what json_serializer from_json() method throws Notes \u00b6 Undefined behavior Writing data to the pointee (overload 3) of the result yields an undefined state. Examples \u00b6 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 < bool > (); auto v2 = json_types [ \"number\" ][ \"integer\" ]. get < int > (); auto v3 = json_types [ \"number\" ][ \"integer\" ]. get < short > (); auto v4 = json_types [ \"number\" ][ \"floating-point\" ]. get < float > (); auto v5 = json_types [ \"number\" ][ \"floating-point\" ]. get < int > (); auto v6 = json_types [ \"string\" ]. get < std :: string > (); auto v7 = json_types [ \"array\" ]. get < std :: vector < short >> (); auto v8 = json_types . get < std :: unordered_map < std :: string , json >> (); // 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 s tr i n g : \"Hello, world!\" nu mber : { \"floating-point\" : 17.23 , \"integer\" : 42 } null : null boolea n : 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 < const json :: number_integer_t *> (); auto p2 = value . get < json :: number_integer_t *> (); auto p3 = value . get < json :: number_integer_t * const > (); auto p4 = value . get < const json :: number_integer_t * const > (); auto p5 = value . get < json :: number_float_t *> (); // print the pointees std :: cout << * p1 << ' ' << * p2 << ' ' << * p3 << ' ' << * p4 << '\\n' ; std :: cout << std :: boolalpha << ( p5 == nullptr ) << '\\n' ; } Output: 17 17 17 17 true Version history \u00b6 Since version 2.1.0. Since version 2.1.0. Extended to work with other specializations of basic_json in version 3.2.0. Since version 1.0.0.","title":"get"},{"location":"api/basic_json/get/#nlohmannbasic_jsonget","text":"// (1) template < typename ValueType > ValueType get () const noexcept ( noexcept ( JSONSerializer < ValueType >:: from_json ( std :: declval < const basic_json_t &> (), std :: declval < ValueType &> ()))); // (2) template < typename BasicJsonType > BasicJsonType get () const ; // (3) template < typename PointerType > PointerType get_ptr (); template < typename PointerType > constexpr const PointerType get_ptr () const noexcept ; Explicit type conversion between the JSON value and a compatible value which is CopyConstructible and DefaultConstructible . The value is converted by calling the json_serializer from_json() method. The function is equivalent to executing ValueType ret ; JSONSerializer < ValueType >:: 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 and not DefaultConstructible , the value is converted by calling the json_serializer from_json() method. The function is then equivalent to executing return JSONSerializer < ValueTypeCV >:: 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. Overload for basic_json specializations. The function is equivalent to executing return * this ; Explicit pointer access to the internally stored JSON value. No copies are made.","title":"nlohmann::basic_json::get"},{"location":"api/basic_json/get/#template-parameters","text":"ValueType the value type to return BasicJsonType a specialization of basic_json PointerType pointer type; must be a pointer to array_t , object_t , string_t , boolean_t , number_integer_t , or number_unsigned_t , number_float_t , or binary_t . Other types will not compile.","title":"Template parameters"},{"location":"api/basic_json/get/#return-value","text":"copy of the JSON value, converted to ValueType a copy of * this , converted into BasicJsonType pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise","title":"Return value"},{"location":"api/basic_json/get/#exceptions","text":"Depends on what json_serializer from_json() method throws","title":"Exceptions"},{"location":"api/basic_json/get/#notes","text":"Undefined behavior Writing data to the pointee (overload 3) of the result yields an undefined state.","title":"Notes"},{"location":"api/basic_json/get/#examples","text":"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 < bool > (); auto v2 = json_types [ \"number\" ][ \"integer\" ]. get < int > (); auto v3 = json_types [ \"number\" ][ \"integer\" ]. get < short > (); auto v4 = json_types [ \"number\" ][ \"floating-point\" ]. get < float > (); auto v5 = json_types [ \"number\" ][ \"floating-point\" ]. get < int > (); auto v6 = json_types [ \"string\" ]. get < std :: string > (); auto v7 = json_types [ \"array\" ]. get < std :: vector < short >> (); auto v8 = json_types . get < std :: unordered_map < std :: string , json >> (); // 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 s tr i n g : \"Hello, world!\" nu mber : { \"floating-point\" : 17.23 , \"integer\" : 42 } null : null boolea n : 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 < const json :: number_integer_t *> (); auto p2 = value . get < json :: number_integer_t *> (); auto p3 = value . get < json :: number_integer_t * const > (); auto p4 = value . get < const json :: number_integer_t * const > (); auto p5 = value . get < json :: number_float_t *> (); // print the pointees std :: cout << * p1 << ' ' << * p2 << ' ' << * p3 << ' ' << * p4 << '\\n' ; std :: cout << std :: boolalpha << ( p5 == nullptr ) << '\\n' ; } Output: 17 17 17 17 true","title":"Examples"},{"location":"api/basic_json/get/#version-history","text":"Since version 2.1.0. Since version 2.1.0. Extended to work with other specializations of basic_json in version 3.2.0. Since version 1.0.0.","title":"Version history"},{"location":"api/basic_json/get_allocator/","text":"nlohmann::basic_json:: get_allocator \u00b6 static allocator_type get_allocator (); Returns the allocator associated with the container. Return value \u00b6 associated allocator Examples \u00b6 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 < decltype ( alloc ) > ; 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 \u00b6 Added in version 1.0.0.","title":"get_allocator"},{"location":"api/basic_json/get_allocator/#nlohmannbasic_jsonget_allocator","text":"static allocator_type get_allocator (); Returns the allocator associated with the container.","title":"nlohmann::basic_json::get_allocator"},{"location":"api/basic_json/get_allocator/#return-value","text":"associated allocator","title":"Return value"},{"location":"api/basic_json/get_allocator/#examples","text":"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 < decltype ( alloc ) > ; 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!\"","title":"Examples"},{"location":"api/basic_json/get_allocator/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/get_binary/","text":"nlohmann::basic_json:: get_binary \u00b6 binary_t & get_binary (); const binary_t & get_binary () const ; Returns a reference to the stored binary value. Return value \u00b6 Reference to binary value. Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 Throws type_error.302 if the value is not binary Complexity \u00b6 Constant. Examples \u00b6 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 < std :: uint8_t > 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: t ype : bi nar y , sub t ype : 42 Version history \u00b6 Added in version 3.8.0.","title":"get_binary"},{"location":"api/basic_json/get_binary/#nlohmannbasic_jsonget_binary","text":"binary_t & get_binary (); const binary_t & get_binary () const ; Returns a reference to the stored binary value.","title":"nlohmann::basic_json::get_binary"},{"location":"api/basic_json/get_binary/#return-value","text":"Reference to binary value.","title":"Return value"},{"location":"api/basic_json/get_binary/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/get_binary/#exceptions","text":"Throws type_error.302 if the value is not binary","title":"Exceptions"},{"location":"api/basic_json/get_binary/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/get_binary/#examples","text":"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 < std :: uint8_t > 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: t ype : bi nar y , sub t ype : 42","title":"Examples"},{"location":"api/basic_json/get_binary/#version-history","text":"Added in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/get_ptr/","text":"nlohmann::basic_json:: get_ptr \u00b6 template < typename PointerType > PointerType get_ptr () noexcept ; template < typename PointerType > constexpr const PointerType get_ptr () const noexcept ; Implicit pointer access to the internally stored JSON value. No copies are made. Template parameters \u00b6 PointerType pointer type; must be a pointer to array_t , object_t , string_t , boolean_t , number_integer_t , or number_unsigned_t , number_float_t , or binary_t . Other types will not compile. Return value \u00b6 pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant. Notes \u00b6 Undefined behavior Writing data to the pointee of the result yields an undefined state. Examples \u00b6 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 < const json :: number_integer_t *> (); auto p2 = value . get_ptr < json :: number_integer_t *> (); auto p3 = value . get_ptr < json :: number_integer_t * const > (); auto p4 = value . get_ptr < const json :: number_integer_t * const > (); auto p5 = value . get_ptr < json :: number_float_t *> (); // print the pointees std :: cout << * p1 << ' ' << * p2 << ' ' << * p3 << ' ' << * p4 << '\\n' ; std :: cout << std :: boolalpha << ( p5 == nullptr ) << '\\n' ; } Output: 17 17 17 17 true Version history \u00b6 Added in version 1.0.0. Extended to binary types in version 3.8.0.","title":"get_ptr"},{"location":"api/basic_json/get_ptr/#nlohmannbasic_jsonget_ptr","text":"template < typename PointerType > PointerType get_ptr () noexcept ; template < typename PointerType > constexpr const PointerType get_ptr () const noexcept ; Implicit pointer access to the internally stored JSON value. No copies are made.","title":"nlohmann::basic_json::get_ptr"},{"location":"api/basic_json/get_ptr/#template-parameters","text":"PointerType pointer type; must be a pointer to array_t , object_t , string_t , boolean_t , number_integer_t , or number_unsigned_t , number_float_t , or binary_t . Other types will not compile.","title":"Template parameters"},{"location":"api/basic_json/get_ptr/#return-value","text":"pointer to the internally stored JSON value if the requested pointer type fits to the JSON value; nullptr otherwise","title":"Return value"},{"location":"api/basic_json/get_ptr/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/get_ptr/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/get_ptr/#notes","text":"Undefined behavior Writing data to the pointee of the result yields an undefined state.","title":"Notes"},{"location":"api/basic_json/get_ptr/#examples","text":"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 < const json :: number_integer_t *> (); auto p2 = value . get_ptr < json :: number_integer_t *> (); auto p3 = value . get_ptr < json :: number_integer_t * const > (); auto p4 = value . get_ptr < const json :: number_integer_t * const > (); auto p5 = value . get_ptr < json :: number_float_t *> (); // print the pointees std :: cout << * p1 << ' ' << * p2 << ' ' << * p3 << ' ' << * p4 << '\\n' ; std :: cout << std :: boolalpha << ( p5 == nullptr ) << '\\n' ; } Output: 17 17 17 17 true","title":"Examples"},{"location":"api/basic_json/get_ptr/#version-history","text":"Added in version 1.0.0. Extended to binary types in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/get_ref/","text":"nlohmann::basic_json:: get_ref \u00b6 template < typename ReferenceType > ReferenceType get_ref (); template < typename ReferenceType > const ReferenceType get_ref () const ; Implicit reference access to the internally stored JSON value. No copies are made. Template parameters \u00b6 ReferenceType reference type; must be a reference to array_t , object_t , string_t , boolean_t , number_integer_t , or number_unsigned_t , number_float_t , or binary_t . Enforced by a static assertion. Return value \u00b6 reference to the internally stored JSON value if the requested reference type fits to the JSON value; throws type_error.303 otherwise Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 Throws type_error.303 if the requested reference type does not match the stored JSON value type; example: \"incompatible ReferenceType for get_ref, actual type is binary\" . Complexity \u00b6 Constant. Notes \u00b6 Undefined behavior Writing data to the referee of the result yields an undefined state. Examples \u00b6 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 < const json :: number_integer_t &> (); auto r2 = value . get_ref < json :: number_integer_t &> (); // print the values std :: cout << r1 << ' ' << r2 << '\\n' ; // incompatible type throws exception try { auto r3 = value . get_ref < json :: number_float_t &> (); } catch ( json :: type_error & ex ) { std :: cout << ex . what () << '\\n' ; } } Output: 17 17 [ jso n .excep t io n . t ype_error. 303 ] i n compa t ible Re feren ceType f or ge t _re f , ac tual t ype is nu mber Version history \u00b6 Added in version 1.1.0. Extended to binary types in version 3.8.0.","title":"get_ref"},{"location":"api/basic_json/get_ref/#nlohmannbasic_jsonget_ref","text":"template < typename ReferenceType > ReferenceType get_ref (); template < typename ReferenceType > const ReferenceType get_ref () const ; Implicit reference access to the internally stored JSON value. No copies are made.","title":"nlohmann::basic_json::get_ref"},{"location":"api/basic_json/get_ref/#template-parameters","text":"ReferenceType reference type; must be a reference to array_t , object_t , string_t , boolean_t , number_integer_t , or number_unsigned_t , number_float_t , or binary_t . Enforced by a static assertion.","title":"Template parameters"},{"location":"api/basic_json/get_ref/#return-value","text":"reference to the internally stored JSON value if the requested reference type fits to the JSON value; throws type_error.303 otherwise","title":"Return value"},{"location":"api/basic_json/get_ref/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/get_ref/#exceptions","text":"Throws type_error.303 if the requested reference type does not match the stored JSON value type; example: \"incompatible ReferenceType for get_ref, actual type is binary\" .","title":"Exceptions"},{"location":"api/basic_json/get_ref/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/get_ref/#notes","text":"Undefined behavior Writing data to the referee of the result yields an undefined state.","title":"Notes"},{"location":"api/basic_json/get_ref/#examples","text":"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 < const json :: number_integer_t &> (); auto r2 = value . get_ref < json :: number_integer_t &> (); // print the values std :: cout << r1 << ' ' << r2 << '\\n' ; // incompatible type throws exception try { auto r3 = value . get_ref < json :: number_float_t &> (); } catch ( json :: type_error & ex ) { std :: cout << ex . what () << '\\n' ; } } Output: 17 17 [ jso n .excep t io n . t ype_error. 303 ] i n compa t ible Re feren ceType f or ge t _re f , ac tual t ype is nu mber","title":"Examples"},{"location":"api/basic_json/get_ref/#version-history","text":"Added in version 1.1.0. Extended to binary types in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/get_to/","text":"nlohmann::basic_json:: get_to \u00b6 template < typename ValueType > ValueType & get_to ( ValueType & v ) const noexcept ( noexcept ( JSONSerializer < ValueType >:: from_json ( std :: declval < const basic_json_t &> (), 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 < ValueType >:: 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 \u00b6 ValueType the value type to return Return value \u00b6 the input parameter, allowing chaining calls Exceptions \u00b6 Depends on what json_serializer from_json() method throws Examples \u00b6 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 < short > , (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 < short > v7 ; std :: unordered_map < std :: string , json > 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 s tr i n g : \"Hello, world!\" nu mber : { \"floating-point\" : 17.23 , \"integer\" : 42 } null : null boolea n : true array : [ 1 , 2 , 3 , 4 , 5 ] Version history \u00b6 Since version 3.3.0.","title":"get_to"},{"location":"api/basic_json/get_to/#nlohmannbasic_jsonget_to","text":"template < typename ValueType > ValueType & get_to ( ValueType & v ) const noexcept ( noexcept ( JSONSerializer < ValueType >:: from_json ( std :: declval < const basic_json_t &> (), 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 < ValueType >:: 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&)","title":"nlohmann::basic_json::get_to"},{"location":"api/basic_json/get_to/#template-parameters","text":"ValueType the value type to return","title":"Template parameters"},{"location":"api/basic_json/get_to/#return-value","text":"the input parameter, allowing chaining calls","title":"Return value"},{"location":"api/basic_json/get_to/#exceptions","text":"Depends on what json_serializer from_json() method throws","title":"Exceptions"},{"location":"api/basic_json/get_to/#examples","text":"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 < short > , (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 < short > v7 ; std :: unordered_map < std :: string , json > 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 s tr i n g : \"Hello, world!\" nu mber : { \"floating-point\" : 17.23 , \"integer\" : 42 } null : null boolea n : true array : [ 1 , 2 , 3 , 4 , 5 ]","title":"Examples"},{"location":"api/basic_json/get_to/#version-history","text":"Since version 3.3.0.","title":"Version history"},{"location":"api/basic_json/input_format_t/","text":"nlohmann::basic_json:: input_format_t \u00b6 enum class input_format_t { json , cbor , msgpack , ubjson , bson , bjdata }; This enumeration is used in the sax_parse 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 \u00b6 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 < std :: string > 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 < std :: uint8_t > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: bi nar y(val= [ ... ] ) resul t : true Version history \u00b6 Added in version 3.2.0.","title":"input_format_t"},{"location":"api/basic_json/input_format_t/#nlohmannbasic_jsoninput_format_t","text":"enum class input_format_t { json , cbor , msgpack , ubjson , bson , bjdata }; This enumeration is used in the sax_parse 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)","title":"nlohmann::basic_json::input_format_t"},{"location":"api/basic_json/input_format_t/#examples","text":"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 < std :: string > 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 < std :: uint8_t > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: bi nar y(val= [ ... ] ) resul t : true","title":"Examples"},{"location":"api/basic_json/input_format_t/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/basic_json/insert/","text":"nlohmann::basic_json:: insert \u00b6 // (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 ); Inserts element val into array before iterator pos . Inserts cnt copies of val into array before iterator pos . Inserts elements from range [first, last) into array before iterator pos . Inserts elements from initializer list ilist into array before iterator pos . Inserts elements from range [first, last) into object. Parameters \u00b6 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) begin of the range of elements to insert last (in) end of the range of elements to insert ilist (in) initializer list to insert the values from Return value \u00b6 iterator pointing to the inserted val . iterator pointing to the first element inserted, or pos if cnt == 0 iterator pointing to the first element inserted, or pos if first == last iterator pointing to the first element inserted, or pos if ilist is empty (none) Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 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 if first and last do not belong to the same JSON value; example: \"iterators do not fit\" Throws invalid_iterator.211 if first or last are iterators into container for which insert is called; example: \"passed iterators may not belong to container\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than objects; example: \"cannot use insert() with string\" Throws invalid_iterator.202 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 if first and last do not belong to the same JSON value; example: \"iterators do not fit\" Complexity \u00b6 Constant plus linear in the distance between pos and end of the container. Linear in cnt plus linear in the distance between pos and end of the container. Linear in std :: distance ( first , last ) plus linear in the distance between pos and end of the container. Linear in ilist.size() plus linear in the distance between pos and end of the container. Logarithmic: O(N*log(size() + N)) , where N is the number of elements to insert. Examples \u00b6 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 range of elements 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 }; // 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 initializer list 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 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 range of elements into 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\" } Version history \u00b6 Added in version 1.0.0. Added in version 1.0.0. Added in version 1.0.0. Added in version 1.0.0. Added in version 3.0.0.","title":"insert"},{"location":"api/basic_json/insert/#nlohmannbasic_jsoninsert","text":"// (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 ); Inserts element val into array before iterator pos . Inserts cnt copies of val into array before iterator pos . Inserts elements from range [first, last) into array before iterator pos . Inserts elements from initializer list ilist into array before iterator pos . Inserts elements from range [first, last) into object.","title":"nlohmann::basic_json::insert"},{"location":"api/basic_json/insert/#parameters","text":"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) begin of the range of elements to insert last (in) end of the range of elements to insert ilist (in) initializer list to insert the values from","title":"Parameters"},{"location":"api/basic_json/insert/#return-value","text":"iterator pointing to the inserted val . iterator pointing to the first element inserted, or pos if cnt == 0 iterator pointing to the first element inserted, or pos if first == last iterator pointing to the first element inserted, or pos if ilist is empty (none)","title":"Return value"},{"location":"api/basic_json/insert/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/insert/#exceptions","text":"The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 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 if first and last do not belong to the same JSON value; example: \"iterators do not fit\" Throws invalid_iterator.211 if first or last are iterators into container for which insert is called; example: \"passed iterators may not belong to container\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than arrays; example: \"cannot use insert() with string\" Throws invalid_iterator.202 if called on an iterator which does not belong to the current JSON value; example: \"iterator does not fit current value\" The function can throw the following exceptions: Throws type_error.309 if called on JSON values other than objects; example: \"cannot use insert() with string\" Throws invalid_iterator.202 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 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"","title":"Exceptions"},{"location":"api/basic_json/insert/#complexity","text":"Constant plus linear in the distance between pos and end of the container. Linear in cnt plus linear in the distance between pos and end of the container. Linear in std :: distance ( first , last ) plus linear in the distance between pos and end of the container. Linear in ilist.size() plus linear in the distance between pos and end of the container. Logarithmic: O(N*log(size() + N)) , where N is the number of elements to insert.","title":"Complexity"},{"location":"api/basic_json/insert/#examples","text":"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 range of elements 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 }; // 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 initializer list 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 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 range of elements into 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\" }","title":"Examples"},{"location":"api/basic_json/insert/#version-history","text":"Added in version 1.0.0. Added in version 1.0.0. Added in version 1.0.0. Added in version 1.0.0. Added in version 3.0.0.","title":"Version history"},{"location":"api/basic_json/invalid_iterator/","text":"nlohmann::basic_json:: invalid_iterator \u00b6 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 ). Member functions \u00b6 what - returns explanatory string Member variables \u00b6 id - the id of the exception Examples \u00b6 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 ( json :: invalid_iterator & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .i n valid_i terat or. 207 ] ca nn o t use key() f or n o n - objec t i terat ors excep t io n id : 207 See also \u00b6 List of iterator errors parse_error for exceptions indicating a parse error type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors Version history \u00b6 Since version 3.0.0.","title":"invalid_iterator"},{"location":"api/basic_json/invalid_iterator/#nlohmannbasic_jsoninvalid_iterator","text":"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 ).","title":"nlohmann::basic_json::invalid_iterator"},{"location":"api/basic_json/invalid_iterator/#member-functions","text":"what - returns explanatory string","title":"Member functions"},{"location":"api/basic_json/invalid_iterator/#member-variables","text":"id - the id of the exception","title":"Member variables"},{"location":"api/basic_json/invalid_iterator/#examples","text":"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 ( json :: invalid_iterator & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .i n valid_i terat or. 207 ] ca nn o t use key() f or n o n - objec t i terat ors excep t io n id : 207","title":"Examples"},{"location":"api/basic_json/invalid_iterator/#see-also","text":"List of iterator errors parse_error for exceptions indicating a parse error type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors","title":"See also"},{"location":"api/basic_json/invalid_iterator/#version-history","text":"Since version 3.0.0.","title":"Version history"},{"location":"api/basic_json/is_array/","text":"nlohmann::basic_json:: is_array \u00b6 constexpr bool is_array () const noexcept ; This function returns true if and only if the JSON value is an array. Return value \u00b6 true if type is an array, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"is_array"},{"location":"api/basic_json/is_array/#nlohmannbasic_jsonis_array","text":"constexpr bool is_array () const noexcept ; This function returns true if and only if the JSON value is an array.","title":"nlohmann::basic_json::is_array"},{"location":"api/basic_json/is_array/#return-value","text":"true if type is an array, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_array/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_array/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_array/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_array/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/is_binary/","text":"nlohmann::basic_json:: is_binary \u00b6 constexpr bool is_binary () const noexcept ; This function returns true if and only if the JSON value is binary array. Return value \u00b6 true if type is binary, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 3.8.0.","title":"is_binary"},{"location":"api/basic_json/is_binary/#nlohmannbasic_jsonis_binary","text":"constexpr bool is_binary () const noexcept ; This function returns true if and only if the JSON value is binary array.","title":"nlohmann::basic_json::is_binary"},{"location":"api/basic_json/is_binary/#return-value","text":"true if type is binary, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_binary/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_binary/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_binary/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_binary/#version-history","text":"Added in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/is_boolean/","text":"nlohmann::basic_json:: is_boolean \u00b6 constexpr bool is_boolean () const noexcept ; This function returns true if and only if the JSON value is true or false . Return value \u00b6 true if type is boolean, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"is_boolean"},{"location":"api/basic_json/is_boolean/#nlohmannbasic_jsonis_boolean","text":"constexpr bool is_boolean () const noexcept ; This function returns true if and only if the JSON value is true or false .","title":"nlohmann::basic_json::is_boolean"},{"location":"api/basic_json/is_boolean/#return-value","text":"true if type is boolean, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_boolean/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_boolean/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_boolean/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_boolean/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/is_discarded/","text":"nlohmann::basic_json:: is_discarded \u00b6 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 ), or the value is the result of parsing invalid JSON with parameter allow_exceptions set to false ; see parse for more information. Return value \u00b6 true if type is discarded, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Notes \u00b6 Comparisons Discarded values are never compared equal with operator== . 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 ) 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. Only if the top-level value is discarded, the return value of the parse call is discarded. This function will always be false for JSON values after parsing. That is, discarded values can only occur during parsing, but will be removed when inside a structured value or replaced by null in other cases. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"is_discarded"},{"location":"api/basic_json/is_discarded/#nlohmannbasic_jsonis_discarded","text":"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 ), or the value is the result of parsing invalid JSON with parameter allow_exceptions set to false ; see parse for more information.","title":"nlohmann::basic_json::is_discarded"},{"location":"api/basic_json/is_discarded/#return-value","text":"true if type is discarded, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_discarded/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_discarded/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_discarded/#notes","text":"Comparisons Discarded values are never compared equal with operator== . 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 ) 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. Only if the top-level value is discarded, the return value of the parse call is discarded. This function will always be false for JSON values after parsing. That is, discarded values can only occur during parsing, but will be removed when inside a structured value or replaced by null in other cases.","title":"Notes"},{"location":"api/basic_json/is_discarded/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_discarded/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/is_null/","text":"nlohmann::basic_json:: is_null \u00b6 constexpr bool is_null () const noexcept ; This function returns true if and only if the JSON value is null . Return value \u00b6 true if type is null , false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"is_null"},{"location":"api/basic_json/is_null/#nlohmannbasic_jsonis_null","text":"constexpr bool is_null () const noexcept ; This function returns true if and only if the JSON value is null .","title":"nlohmann::basic_json::is_null"},{"location":"api/basic_json/is_null/#return-value","text":"true if type is null , false otherwise.","title":"Return value"},{"location":"api/basic_json/is_null/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_null/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_null/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_null/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/is_number/","text":"nlohmann::basic_json:: is_number \u00b6 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 \u00b6 true if type is number (regardless whether integer, unsigned integer or floating-type), false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Possible implementation \u00b6 constexpr bool is_number () const noexcept { return is_number_integer () || is_number_float (); } Examples \u00b6 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 \u00b6 is_number_integer() check if value is an integer or unsigned integer number is_number_unsigned() check if value is an unsigned integer number is_number_float() check if value is a floating-point number Version history \u00b6 Added in version 1.0.0. Extended to also return true for unsigned integers in 2.0.0.","title":"is_number"},{"location":"api/basic_json/is_number/#nlohmannbasic_jsonis_number","text":"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.","title":"nlohmann::basic_json::is_number"},{"location":"api/basic_json/is_number/#return-value","text":"true if type is number (regardless whether integer, unsigned integer or floating-type), false otherwise.","title":"Return value"},{"location":"api/basic_json/is_number/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_number/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_number/#possible-implementation","text":"constexpr bool is_number () const noexcept { return is_number_integer () || is_number_float (); }","title":"Possible implementation"},{"location":"api/basic_json/is_number/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_number/#see-also","text":"is_number_integer() check if value is an integer or unsigned integer number is_number_unsigned() check if value is an unsigned integer number is_number_float() check if value is a floating-point number","title":"See also"},{"location":"api/basic_json/is_number/#version-history","text":"Added in version 1.0.0. Extended to also return true for unsigned integers in 2.0.0.","title":"Version history"},{"location":"api/basic_json/is_number_float/","text":"nlohmann::basic_json:: is_number_float \u00b6 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 \u00b6 true if type is a floating-point number, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 is_number() check if value is a number is_number_integer() check if value is an integer or unsigned integer number is_number_unsigned() check if value is an unsigned integer number Version history \u00b6 Added in version 1.0.0.","title":"is_number_float"},{"location":"api/basic_json/is_number_float/#nlohmannbasic_jsonis_number_float","text":"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.","title":"nlohmann::basic_json::is_number_float"},{"location":"api/basic_json/is_number_float/#return-value","text":"true if type is a floating-point number, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_number_float/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_number_float/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_number_float/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_number_float/#see-also","text":"is_number() check if value is a number is_number_integer() check if value is an integer or unsigned integer number is_number_unsigned() check if value is an unsigned integer number","title":"See also"},{"location":"api/basic_json/is_number_float/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/is_number_integer/","text":"nlohmann::basic_json:: is_number_integer \u00b6 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 \u00b6 true if type is an integer or unsigned integer number, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 is_number() check if value is a number is_number_unsigned() check if value is an unsigned integer number is_number_float() check if value is a floating-point number Version history \u00b6 Added in version 1.0.0. Extended to also return true for unsigned integers in 2.0.0.","title":"is_number_integer"},{"location":"api/basic_json/is_number_integer/#nlohmannbasic_jsonis_number_integer","text":"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.","title":"nlohmann::basic_json::is_number_integer"},{"location":"api/basic_json/is_number_integer/#return-value","text":"true if type is an integer or unsigned integer number, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_number_integer/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_number_integer/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_number_integer/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_number_integer/#see-also","text":"is_number() check if value is a number is_number_unsigned() check if value is an unsigned integer number is_number_float() check if value is a floating-point number","title":"See also"},{"location":"api/basic_json/is_number_integer/#version-history","text":"Added in version 1.0.0. Extended to also return true for unsigned integers in 2.0.0.","title":"Version history"},{"location":"api/basic_json/is_number_unsigned/","text":"nlohmann::basic_json:: is_number_unsigned \u00b6 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 \u00b6 true if type is an unsigned integer number, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 is_number() check if value is a number is_number_integer() check if value is an integer or unsigned integer number is_number_float() check if value is a floating-point number Version history \u00b6 Added in version 2.0.0.","title":"is_number_unsigned"},{"location":"api/basic_json/is_number_unsigned/#nlohmannbasic_jsonis_number_unsigned","text":"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.","title":"nlohmann::basic_json::is_number_unsigned"},{"location":"api/basic_json/is_number_unsigned/#return-value","text":"true if type is an unsigned integer number, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_number_unsigned/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_number_unsigned/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_number_unsigned/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_number_unsigned/#see-also","text":"is_number() check if value is a number is_number_integer() check if value is an integer or unsigned integer number is_number_float() check if value is a floating-point number","title":"See also"},{"location":"api/basic_json/is_number_unsigned/#version-history","text":"Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/is_object/","text":"nlohmann::basic_json:: is_object \u00b6 constexpr bool is_object () const noexcept ; This function returns true if and only if the JSON value is an object. Return value \u00b6 true if type is an object, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"is_object"},{"location":"api/basic_json/is_object/#nlohmannbasic_jsonis_object","text":"constexpr bool is_object () const noexcept ; This function returns true if and only if the JSON value is an object.","title":"nlohmann::basic_json::is_object"},{"location":"api/basic_json/is_object/#return-value","text":"true if type is an object, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_object/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_object/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_object/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_object/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/is_primitive/","text":"nlohmann::basic_json:: is_primitive \u00b6 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 \u00b6 true if type is primitive (string, number, boolean, null , or binary), false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Possible implementation \u00b6 constexpr bool is_primitive () const noexcept { return is_null () || is_string () || is_boolean () || is_number () || is_binary (); } Notes \u00b6 The term primitive stems from RFC 8259 : 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 \u00b6 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 \u00b6 is_structured() returns whether JSON value is structured is_null() returns whether JSON value is null is_string() returns whether JSON value is a string is_boolean() returns whether JSON value is a boolean is_number() returns whether JSON value is a number is_binary() returns whether JSON value is a binary array Version history \u00b6 Added in version 1.0.0. Extended to return true for binary types in version 3.8.0.","title":"is_primitive"},{"location":"api/basic_json/is_primitive/#nlohmannbasic_jsonis_primitive","text":"constexpr bool is_primitive () const noexcept ; This function returns true if and only if the JSON type is primitive (string, number, boolean, null , binary).","title":"nlohmann::basic_json::is_primitive"},{"location":"api/basic_json/is_primitive/#return-value","text":"true if type is primitive (string, number, boolean, null , or binary), false otherwise.","title":"Return value"},{"location":"api/basic_json/is_primitive/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_primitive/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_primitive/#possible-implementation","text":"constexpr bool is_primitive () const noexcept { return is_null () || is_string () || is_boolean () || is_number () || is_binary (); }","title":"Possible implementation"},{"location":"api/basic_json/is_primitive/#notes","text":"The term primitive stems from RFC 8259 : 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.","title":"Notes"},{"location":"api/basic_json/is_primitive/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_primitive/#see-also","text":"is_structured() returns whether JSON value is structured is_null() returns whether JSON value is null is_string() returns whether JSON value is a string is_boolean() returns whether JSON value is a boolean is_number() returns whether JSON value is a number is_binary() returns whether JSON value is a binary array","title":"See also"},{"location":"api/basic_json/is_primitive/#version-history","text":"Added in version 1.0.0. Extended to return true for binary types in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/is_string/","text":"nlohmann::basic_json:: is_string \u00b6 constexpr bool is_string () const noexcept ; This function returns true if and only if the JSON value is a string. Return value \u00b6 true if type is a string, false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"is_string"},{"location":"api/basic_json/is_string/#nlohmannbasic_jsonis_string","text":"constexpr bool is_string () const noexcept ; This function returns true if and only if the JSON value is a string.","title":"nlohmann::basic_json::is_string"},{"location":"api/basic_json/is_string/#return-value","text":"true if type is a string, false otherwise.","title":"Return value"},{"location":"api/basic_json/is_string/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_string/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_string/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_string/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/is_structured/","text":"nlohmann::basic_json:: is_structured \u00b6 constexpr bool is_structured () const noexcept ; This function returns true if and only if the JSON type is structured (array or object). Return value \u00b6 true if type is structured (array or object), false otherwise. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Possible implementation \u00b6 constexpr bool is_primitive () const noexcept { return is_array () || is_object (); } Notes \u00b6 The term structured stems from RFC 8259 : 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 \u00b6 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 \u00b6 is_primitive() returns whether JSON value is primitive is_array() returns whether value is an array is_object() returns whether value is an object Version history \u00b6 Added in version 1.0.0.","title":"is_structured"},{"location":"api/basic_json/is_structured/#nlohmannbasic_jsonis_structured","text":"constexpr bool is_structured () const noexcept ; This function returns true if and only if the JSON type is structured (array or object).","title":"nlohmann::basic_json::is_structured"},{"location":"api/basic_json/is_structured/#return-value","text":"true if type is structured (array or object), false otherwise.","title":"Return value"},{"location":"api/basic_json/is_structured/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/is_structured/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/is_structured/#possible-implementation","text":"constexpr bool is_primitive () const noexcept { return is_array () || is_object (); }","title":"Possible implementation"},{"location":"api/basic_json/is_structured/#notes","text":"The term structured stems from RFC 8259 : 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.","title":"Notes"},{"location":"api/basic_json/is_structured/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/is_structured/#see-also","text":"is_primitive() returns whether JSON value is primitive is_array() returns whether value is an array is_object() returns whether value is an object","title":"See also"},{"location":"api/basic_json/is_structured/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/items/","text":"nlohmann::basic_json:: items \u00b6 iteration_proxy < iterator > items () noexcept ; iteration_proxy < const_iterator > 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 (C++17): for ( auto & [ key , val ] : j_object . items ()) { std :: cout << \"key: \" << key << \", value:\" << val << '\\n' ; } Return value \u00b6 iteration proxy object wrapping the current value with an interface to use in range-based for loops Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Constant. Notes \u00b6 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 https://github.com/nlohmann/json/issues/2040 for more information. Examples \u00b6 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 : o ne , value : 1 key : t wo , value : 2 key : 0 , value : 1 key : 1 , value : 2 key : 2 , value : 4 key : 3 , value : 8 key : 4 , value : 16 Version history \u00b6 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.","title":"items"},{"location":"api/basic_json/items/#nlohmannbasic_jsonitems","text":"iteration_proxy < iterator > items () noexcept ; iteration_proxy < const_iterator > 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 (C++17): for ( auto & [ key , val ] : j_object . items ()) { std :: cout << \"key: \" << key << \", value:\" << val << '\\n' ; }","title":"nlohmann::basic_json::items"},{"location":"api/basic_json/items/#return-value","text":"iteration proxy object wrapping the current value with an interface to use in range-based for loops","title":"Return value"},{"location":"api/basic_json/items/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/items/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/items/#notes","text":"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 https://github.com/nlohmann/json/issues/2040 for more information.","title":"Notes"},{"location":"api/basic_json/items/#examples","text":"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 : o ne , value : 1 key : t wo , value : 2 key : 0 , value : 1 key : 1 , value : 2 key : 2 , value : 4 key : 3 , value : 8 key : 4 , value : 16","title":"Examples"},{"location":"api/basic_json/items/#version-history","text":"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.","title":"Version history"},{"location":"api/basic_json/json_base_class_t/","text":"nlohmann::basic_json:: json_base_class_t \u00b6 using json_base_class_t = detail :: json_base_class < CustomBaseClass > ; 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 \u00b6 CustomBaseClass the base class to be added to basic_json Notes \u00b6 Default type \u00b6 The default value for CustomBaseClass is void . In this case an empty base class is used and no additional functionality is injected. Limitations \u00b6 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 \u00b6 Example The following code shows how to inject custom data and methods for each node. #include #include class visitor_adaptor_with_metadata { public : template < class Fnc > void visit ( const Fnc & fnc ) const ; int metadata = 42 ; private : template < class Ptr , class Fnc > 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 < std :: uint8_t > , visitor_adaptor_with_metadata > ; template < class Fnc > void visitor_adaptor_with_metadata :: visit ( const Fnc & fnc ) const { do_visit ( json :: json_pointer {}, fnc ); } template < class Ptr , class Fnc > 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 < const json *> ( 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: / - me ta da ta = 42 - > { \"null\" : null , \"object\" :{ \"uint\" : 1 }} / null - me ta da ta = 42 - > null /objec t - me ta da ta = 21 - > { \"uint\" : 1 } /objec t /ui nt - me ta da ta = 42 - > 1 Version history \u00b6 Added in version 3.12.0.","title":"json_base_class_t"},{"location":"api/basic_json/json_base_class_t/#nlohmannbasic_jsonjson_base_class_t","text":"using json_base_class_t = detail :: json_base_class < CustomBaseClass > ; 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.","title":"nlohmann::basic_json::json_base_class_t"},{"location":"api/basic_json/json_base_class_t/#template-parameters","text":"CustomBaseClass the base class to be added to basic_json","title":"Template parameters"},{"location":"api/basic_json/json_base_class_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/json_base_class_t/#default-type","text":"The default value for CustomBaseClass is void . In this case an empty base class is used and no additional functionality is injected.","title":"Default type"},{"location":"api/basic_json/json_base_class_t/#limitations","text":"The type CustomBaseClass has to be a default-constructible class. basic_json only supports copy/move construction/assignment if CustomBaseClass does so as well.","title":"Limitations"},{"location":"api/basic_json/json_base_class_t/#examples","text":"Example The following code shows how to inject custom data and methods for each node. #include #include class visitor_adaptor_with_metadata { public : template < class Fnc > void visit ( const Fnc & fnc ) const ; int metadata = 42 ; private : template < class Ptr , class Fnc > 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 < std :: uint8_t > , visitor_adaptor_with_metadata > ; template < class Fnc > void visitor_adaptor_with_metadata :: visit ( const Fnc & fnc ) const { do_visit ( json :: json_pointer {}, fnc ); } template < class Ptr , class Fnc > 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 < const json *> ( 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: / - me ta da ta = 42 - > { \"null\" : null , \"object\" :{ \"uint\" : 1 }} / null - me ta da ta = 42 - > null /objec t - me ta da ta = 21 - > { \"uint\" : 1 } /objec t /ui nt - me ta da ta = 42 - > 1","title":"Examples"},{"location":"api/basic_json/json_base_class_t/#version-history","text":"Added in version 3.12.0.","title":"Version history"},{"location":"api/basic_json/json_serializer/","text":"nlohmann::basic_json:: json_serializer \u00b6 template < typename T , typename SFINAE > using json_serializer = JSONSerializer < T , SFINAE > ; Template parameters \u00b6 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 \u00b6 Default type \u00b6 The default values for json_serializer is adl_serializer . Examples \u00b6 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 < ns :: person > { 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 < ns :: person > (); std :: cout << p . name << \" (\" << p . age << \") lives in \" << p . address << std :: endl ; } Output: Ned Fla n ders ( 60 ) lives i n 744 Evergree n Terrace Version history \u00b6 Since version 2.0.0.","title":"json_serializer"},{"location":"api/basic_json/json_serializer/#nlohmannbasic_jsonjson_serializer","text":"template < typename T , typename SFINAE > using json_serializer = JSONSerializer < T , SFINAE > ;","title":"nlohmann::basic_json::json_serializer"},{"location":"api/basic_json/json_serializer/#template-parameters","text":"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","title":"Template parameters"},{"location":"api/basic_json/json_serializer/#notes","text":"","title":"Notes"},{"location":"api/basic_json/json_serializer/#default-type","text":"The default values for json_serializer is adl_serializer .","title":"Default type"},{"location":"api/basic_json/json_serializer/#examples","text":"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 < ns :: person > { 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 < ns :: person > (); std :: cout << p . name << \" (\" << p . age << \") lives in \" << p . address << std :: endl ; } Output: Ned Fla n ders ( 60 ) lives i n 744 Evergree n Terrace","title":"Examples"},{"location":"api/basic_json/json_serializer/#version-history","text":"Since version 2.0.0.","title":"Version history"},{"location":"api/basic_json/max_size/","text":"nlohmann::basic_json:: max_size \u00b6 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 \u00b6 The return value depends on the different types and is defined as follows: Value type return value null 0 (same as size() ) boolean 1 (same as size() ) string 1 (same as size() ) number 1 (same as size() ) binary 1 (same as size() ) object result of function object_t::max_size() array result of function array_t::max_size() Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant, as long as array_t and object_t satisfy the Container concept; that is, their max_size() functions have constant complexity. Notes \u00b6 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 \u00b6 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 \u00b6 Added in version 1.0.0. Extended to return 1 for binary types in version 3.8.0.","title":"max_size"},{"location":"api/basic_json/max_size/#nlohmannbasic_jsonmax_size","text":"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.","title":"nlohmann::basic_json::max_size"},{"location":"api/basic_json/max_size/#return-value","text":"The return value depends on the different types and is defined as follows: Value type return value null 0 (same as size() ) boolean 1 (same as size() ) string 1 (same as size() ) number 1 (same as size() ) binary 1 (same as size() ) object result of function object_t::max_size() array result of function array_t::max_size()","title":"Return value"},{"location":"api/basic_json/max_size/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/max_size/#complexity","text":"Constant, as long as array_t and object_t satisfy the Container concept; that is, their max_size() functions have constant complexity.","title":"Complexity"},{"location":"api/basic_json/max_size/#notes","text":"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 .","title":"Notes"},{"location":"api/basic_json/max_size/#examples","text":"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.","title":"Examples"},{"location":"api/basic_json/max_size/#version-history","text":"Added in version 1.0.0. Extended to return 1 for binary types in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/merge_patch/","text":"nlohmann::basic_json:: merge_patch \u00b6 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) : 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 \u00b6 apply_patch (in) the patch to apply Complexity \u00b6 Linear in the lengths of apply_patch . Examples \u00b6 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 \u00b6 RFC 7396 (JSON Merge Patch) patch apply a JSON patch Version history \u00b6 Added in version 3.0.0.","title":"merge_patch"},{"location":"api/basic_json/merge_patch/#nlohmannbasic_jsonmerge_patch","text":"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) : 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.","title":"nlohmann::basic_json::merge_patch"},{"location":"api/basic_json/merge_patch/#parameters","text":"apply_patch (in) the patch to apply","title":"Parameters"},{"location":"api/basic_json/merge_patch/#complexity","text":"Linear in the lengths of apply_patch .","title":"Complexity"},{"location":"api/basic_json/merge_patch/#examples","text":"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!\" }","title":"Examples"},{"location":"api/basic_json/merge_patch/#see-also","text":"RFC 7396 (JSON Merge Patch) patch apply a JSON patch","title":"See also"},{"location":"api/basic_json/merge_patch/#version-history","text":"Added in version 3.0.0.","title":"Version history"},{"location":"api/basic_json/meta/","text":"nlohmann::basic_json:: meta \u00b6 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 \u00b6 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). 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 , and string (the version string). Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Complexity \u00b6 Constant. Examples \u00b6 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.1.0\" }, \"copyright\" : \"(C) 2013-2022 Niels Lohmann\" , \"name\" : \"JSON for Modern C++\" , \"platform\" : \"apple\" , \"url\" : \"https://github.com/nlohmann/json\" , \"version\" : { \"major\" : 3 , \"minor\" : 11 , \"patch\" : 2 , \"string\" : \"3.11.2\" } } Note the output is platform-dependent. See also \u00b6 NLOHMANN_JSON_VERSION_MAJOR / NLOHMANN_JSON_VERSION_MINOR / NLOHMANN_JSON_VERSION_PATCH - library version information Version history \u00b6 Added in version 2.1.0.","title":"meta"},{"location":"api/basic_json/meta/#nlohmannbasic_jsonmeta","text":"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.","title":"nlohmann::basic_json::meta"},{"location":"api/basic_json/meta/#return-value","text":"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). 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 , and string (the version string).","title":"Return value"},{"location":"api/basic_json/meta/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes to any JSON value.","title":"Exception safety"},{"location":"api/basic_json/meta/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/meta/#examples","text":"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.1.0\" }, \"copyright\" : \"(C) 2013-2022 Niels Lohmann\" , \"name\" : \"JSON for Modern C++\" , \"platform\" : \"apple\" , \"url\" : \"https://github.com/nlohmann/json\" , \"version\" : { \"major\" : 3 , \"minor\" : 11 , \"patch\" : 2 , \"string\" : \"3.11.2\" } } Note the output is platform-dependent.","title":"Examples"},{"location":"api/basic_json/meta/#see-also","text":"NLOHMANN_JSON_VERSION_MAJOR / NLOHMANN_JSON_VERSION_MINOR / NLOHMANN_JSON_VERSION_PATCH - library version information","title":"See also"},{"location":"api/basic_json/meta/#version-history","text":"Added in version 2.1.0.","title":"Version history"},{"location":"api/basic_json/number_float_t/","text":"nlohmann::basic_json:: number_float_t \u00b6 using number_float_t = NumberFloatType ; The type used to store JSON numbers (floating-point). 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. To store floating-point numbers in C++, a type is defined by the template parameter NumberFloatType which chooses the type to use. Notes \u00b6 Default type \u00b6 With the default values for NumberFloatType ( double ), the default value for number_float_t is double . Default behavior \u00b6 The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in floating-point literals will be ignored. Internally, the value will be stored as 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 \u00b6 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 \u00b6 Floating-point number values are stored directly inside a basic_json type. Examples \u00b6 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 < double , json :: number_float_t >:: value << std :: endl ; } Output: true Version history \u00b6 Added in version 1.0.0.","title":"number_float_t"},{"location":"api/basic_json/number_float_t/#nlohmannbasic_jsonnumber_float_t","text":"using number_float_t = NumberFloatType ; The type used to store JSON numbers (floating-point). 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. To store floating-point numbers in C++, a type is defined by the template parameter NumberFloatType which chooses the type to use.","title":"nlohmann::basic_json::number_float_t"},{"location":"api/basic_json/number_float_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/number_float_t/#default-type","text":"With the default values for NumberFloatType ( double ), the default value for number_float_t is double .","title":"Default type"},{"location":"api/basic_json/number_float_t/#default-behavior","text":"The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in floating-point literals will be ignored. Internally, the value will be stored as 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 .","title":"Default behavior"},{"location":"api/basic_json/number_float_t/#limits","text":"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 .","title":"Limits"},{"location":"api/basic_json/number_float_t/#storage","text":"Floating-point number values are stored directly inside a basic_json type.","title":"Storage"},{"location":"api/basic_json/number_float_t/#examples","text":"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 < double , json :: number_float_t >:: value << std :: endl ; } Output: true","title":"Examples"},{"location":"api/basic_json/number_float_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/number_integer_t/","text":"nlohmann::basic_json:: number_integer_t \u00b6 using number_integer_t = NumberIntegerType ; The type used to store JSON numbers (integers). 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. To store integer numbers in C++, a type is defined by the template parameter NumberIntegerType which chooses the type to use. Notes \u00b6 Default type \u00b6 With the default values for NumberIntegerType ( std::int64_t ), the default value for number_integer_t is std :: int64_t . Default behavior \u00b6 The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 \u00b6 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 be automatically be stored as number_unsigned_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] [-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 \u00b6 Integer number values are stored directly inside a basic_json type. Examples \u00b6 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 < std :: int64_t , json :: number_integer_t >:: value << std :: endl ; } Output: true Version history \u00b6 Added in version 1.0.0.","title":"number_integer_t"},{"location":"api/basic_json/number_integer_t/#nlohmannbasic_jsonnumber_integer_t","text":"using number_integer_t = NumberIntegerType ; The type used to store JSON numbers (integers). 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. To store integer numbers in C++, a type is defined by the template parameter NumberIntegerType which chooses the type to use.","title":"nlohmann::basic_json::number_integer_t"},{"location":"api/basic_json/number_integer_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/number_integer_t/#default-type","text":"With the default values for NumberIntegerType ( std::int64_t ), the default value for number_integer_t is std :: int64_t .","title":"Default type"},{"location":"api/basic_json/number_integer_t/#default-behavior","text":"The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 .","title":"Default behavior"},{"location":"api/basic_json/number_integer_t/#limits","text":"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 be automatically be stored as number_unsigned_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] [-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.","title":"Limits"},{"location":"api/basic_json/number_integer_t/#storage","text":"Integer number values are stored directly inside a basic_json type.","title":"Storage"},{"location":"api/basic_json/number_integer_t/#examples","text":"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 < std :: int64_t , json :: number_integer_t >:: value << std :: endl ; } Output: true","title":"Examples"},{"location":"api/basic_json/number_integer_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/number_unsigned_t/","text":"nlohmann::basic_json:: number_unsigned_t \u00b6 using number_unsigned_t = NumberUnsignedType ; The type used to store JSON numbers (unsigned). 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. To store unsigned integer numbers in C++, a type is defined by the template parameter NumberUnsignedType which chooses the type to use. Notes \u00b6 Default type \u00b6 With the default values for NumberUnsignedType ( std::uint64_t ), the default value for number_unsigned_t is std :: uint64_t . Default behavior \u00b6 The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 \u00b6 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 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 be 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 \\f [-2^{53}+1, 2^{53}-1]\\f [-2^{53}+1, 2^{53}-1]\\f 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 \u00b6 Integer number values are stored directly inside a basic_json type. Examples \u00b6 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 < std :: uint64_t , json :: number_unsigned_t >:: value << std :: endl ; } Output: true Version history \u00b6 Added in version 2.0.0.","title":"number_unsigned_t"},{"location":"api/basic_json/number_unsigned_t/#nlohmannbasic_jsonnumber_unsigned_t","text":"using number_unsigned_t = NumberUnsignedType ; The type used to store JSON numbers (unsigned). 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. To store unsigned integer numbers in C++, a type is defined by the template parameter NumberUnsignedType which chooses the type to use.","title":"nlohmann::basic_json::number_unsigned_t"},{"location":"api/basic_json/number_unsigned_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/number_unsigned_t/#default-type","text":"With the default values for NumberUnsignedType ( std::uint64_t ), the default value for number_unsigned_t is std :: uint64_t .","title":"Default type"},{"location":"api/basic_json/number_unsigned_t/#default-behavior","text":"The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 .","title":"Default behavior"},{"location":"api/basic_json/number_unsigned_t/#limits","text":"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 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 be 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 \\f [-2^{53}+1, 2^{53}-1]\\f [-2^{53}+1, 2^{53}-1]\\f 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.","title":"Limits"},{"location":"api/basic_json/number_unsigned_t/#storage","text":"Integer number values are stored directly inside a basic_json type.","title":"Storage"},{"location":"api/basic_json/number_unsigned_t/#examples","text":"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 < std :: uint64_t , json :: number_unsigned_t >:: value << std :: endl ; } Output: true","title":"Examples"},{"location":"api/basic_json/number_unsigned_t/#version-history","text":"Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/object/","text":"nlohmann::basic_json:: object \u00b6 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 \u00b6 init (in) initializer list with JSON values to create an object from (optional) Return value \u00b6 JSON object value Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws type_error.301 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 example below. Complexity \u00b6 Linear in the size of init . Notes \u00b6 This function is only added for symmetry reasons. In contrast to the related function array(initializer_list_t) , there are no cases which 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 \u00b6 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 ( json :: type_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: {} {} { \"one\" : 1 , \"two\" : 2 } [ jso n .excep t io n . t ype_error. 301 ] ca nn o t crea te objec t fr om i n i t ializer lis t See also \u00b6 basic_json(initializer_list_t) - create a JSON value from an initializer list array - create a JSON array value from an initializer list Version history \u00b6 Added in version 1.0.0.","title":"object"},{"location":"api/basic_json/object/#nlohmannbasic_jsonobject","text":"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.","title":"nlohmann::basic_json::object"},{"location":"api/basic_json/object/#parameters","text":"init (in) initializer list with JSON values to create an object from (optional)","title":"Parameters"},{"location":"api/basic_json/object/#return-value","text":"JSON object value","title":"Return value"},{"location":"api/basic_json/object/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/object/#exceptions","text":"Throws type_error.301 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 example below.","title":"Exceptions"},{"location":"api/basic_json/object/#complexity","text":"Linear in the size of init .","title":"Complexity"},{"location":"api/basic_json/object/#notes","text":"This function is only added for symmetry reasons. In contrast to the related function array(initializer_list_t) , there are no cases which 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) .","title":"Notes"},{"location":"api/basic_json/object/#examples","text":"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 ( json :: type_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: {} {} { \"one\" : 1 , \"two\" : 2 } [ jso n .excep t io n . t ype_error. 301 ] ca nn o t crea te objec t fr om i n i t ializer lis t","title":"Examples"},{"location":"api/basic_json/object/#see-also","text":"basic_json(initializer_list_t) - create a JSON value from an initializer list array - create a JSON array value from an initializer list","title":"See also"},{"location":"api/basic_json/object/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/object_comparator_t/","text":"nlohmann::basic_json:: object_comparator_t \u00b6 using object_comparator_t = typename object_t :: key_compare ; // or using object_comparator_t = default_object_comparator_t ; The comparator used by object_t . Defined as typename object_t :: key_compare if available, and default_object_comparator_t otherwise. Examples \u00b6 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: jso n :: objec t _compara t or_ t ( \"one\" , \"two\" ) = true jso n :: objec t _compara t or_ t ( \"three\" , \"four\" ) = false Version history \u00b6 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.","title":"object_comparator_t"},{"location":"api/basic_json/object_comparator_t/#nlohmannbasic_jsonobject_comparator_t","text":"using object_comparator_t = typename object_t :: key_compare ; // or using object_comparator_t = default_object_comparator_t ; The comparator used by object_t . Defined as typename object_t :: key_compare if available, and default_object_comparator_t otherwise.","title":"nlohmann::basic_json::object_comparator_t"},{"location":"api/basic_json/object_comparator_t/#examples","text":"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: jso n :: objec t _compara t or_ t ( \"one\" , \"two\" ) = true jso n :: objec t _compara t or_ t ( \"three\" , \"four\" ) = false","title":"Examples"},{"location":"api/basic_json/object_comparator_t/#version-history","text":"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.","title":"Version history"},{"location":"api/basic_json/object_t/","text":"nlohmann::basic_json:: object_t \u00b6 using object_t = ObjectType < StringType , basic_json , default_object_comparator_t , AllocatorType < std :: pair < const StringType , basic_json >>> ; The type used to store JSON objects. RFC 8259 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 \u00b6 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 \u00b6 Default type \u00b6 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 < std :: string > , // key_compare std :: allocator < std :: pair < const std :: string , basic_json >> // allocator_type > // since C++14 std :: map < std :: string , // key_type basic_json , // value_type std :: less <> , // key_compare std :: allocator < std :: pair < const std :: string , basic_json >> // allocator_type > See default_object_comparator_t for more information. Behavior \u00b6 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, { \"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 \u00b6 RFC 8259 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 \u00b6 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 \u00b6 The order 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 , because any order implements the specified \"unordered\" nature of JSON objects. Examples \u00b6 Example The following code shows that object_t is by default, a typedef to std :: map < json :: string_t , json > . #include #include #include using json = nlohmann :: json ; int main () { std :: cout << std :: boolalpha << std :: is_same < std :: map < json :: string_t , json > , json :: object_t >:: value << std :: endl ; } Output: true Version history \u00b6 Added in version 1.0.0.","title":"object_t"},{"location":"api/basic_json/object_t/#nlohmannbasic_jsonobject_t","text":"using object_t = ObjectType < StringType , basic_json , default_object_comparator_t , AllocatorType < std :: pair < const StringType , basic_json >>> ; The type used to store JSON objects. RFC 8259 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.","title":"nlohmann::basic_json::object_t"},{"location":"api/basic_json/object_t/#template-parameters","text":"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 )","title":"Template parameters"},{"location":"api/basic_json/object_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/object_t/#default-type","text":"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 < std :: string > , // key_compare std :: allocator < std :: pair < const std :: string , basic_json >> // allocator_type > // since C++14 std :: map < std :: string , // key_type basic_json , // value_type std :: less <> , // key_compare std :: allocator < std :: pair < const std :: string , basic_json >> // allocator_type > See default_object_comparator_t for more information.","title":"Default type"},{"location":"api/basic_json/object_t/#behavior","text":"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, { \"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.","title":"Behavior"},{"location":"api/basic_json/object_t/#limits","text":"RFC 8259 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.","title":"Limits"},{"location":"api/basic_json/object_t/#storage","text":"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.","title":"Storage"},{"location":"api/basic_json/object_t/#object-key-order","text":"The order 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 , because any order implements the specified \"unordered\" nature of JSON objects.","title":"Object key order"},{"location":"api/basic_json/object_t/#examples","text":"Example The following code shows that object_t is by default, a typedef to std :: map < json :: string_t , json > . #include #include #include using json = nlohmann :: json ; int main () { std :: cout << std :: boolalpha << std :: is_same < std :: map < json :: string_t , json > , json :: object_t >:: value << std :: endl ; } Output: true","title":"Examples"},{"location":"api/basic_json/object_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/operator%2B%3D/","text":"nlohmann::basic_json:: operator+= \u00b6 // (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 ); 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 . 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 . This function allows using operator+= with an initializer list. In case the current value is an object, the initializer list init contains only two elements, and 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&&) . Parameters \u00b6 val (in) the value to add to the JSON array/object init (in) an initializer list Return value \u00b6 * this Exceptions \u00b6 All functions can throw the following exception: - Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use operator+=() with number\" Complexity \u00b6 Amortized constant. Logarithmic in the size of the container, O(log( size() )). Linear in the size of the initializer list init . Notes \u00b6 (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 for more information. Examples \u00b6 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 ]] Version history \u00b6 Since version 1.0.0. Since version 1.0.0. Since version 2.0.0.","title":"operator+="},{"location":"api/basic_json/operator%2B%3D/#nlohmannbasic_jsonoperator","text":"// (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 ); 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 . 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 . This function allows using operator+= with an initializer list. In case the current value is an object, the initializer list init contains only two elements, and 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&&) .","title":"nlohmann::basic_json::operator+="},{"location":"api/basic_json/operator%2B%3D/#parameters","text":"val (in) the value to add to the JSON array/object init (in) an initializer list","title":"Parameters"},{"location":"api/basic_json/operator%2B%3D/#return-value","text":"* this","title":"Return value"},{"location":"api/basic_json/operator%2B%3D/#exceptions","text":"All functions can throw the following exception: - Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use operator+=() with number\"","title":"Exceptions"},{"location":"api/basic_json/operator%2B%3D/#complexity","text":"Amortized constant. Logarithmic in the size of the container, O(log( size() )). Linear in the size of the initializer list init .","title":"Complexity"},{"location":"api/basic_json/operator%2B%3D/#notes","text":"(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 for more information.","title":"Notes"},{"location":"api/basic_json/operator%2B%3D/#examples","text":"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 ]]","title":"Examples"},{"location":"api/basic_json/operator%2B%3D/#version-history","text":"Since version 1.0.0. Since version 1.0.0. Since version 2.0.0.","title":"Version history"},{"location":"api/basic_json/operator%3D/","text":"nlohmann::basic_json:: operator= \u00b6 basic_json & operator = ( basic_json other ) noexcept ( std :: is_nothrow_move_constructible < value_t >:: value && std :: is_nothrow_move_assignable < value_t >:: value && std :: is_nothrow_move_constructible < json_value >:: value && std :: is_nothrow_move_assignable < json_value >:: value ); 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 \u00b6 other (in) value to copy from Complexity \u00b6 Linear. Examples \u00b6 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 Version history \u00b6 Added in version 1.0.0.","title":"operator="},{"location":"api/basic_json/operator%3D/#nlohmannbasic_jsonoperator","text":"basic_json & operator = ( basic_json other ) noexcept ( std :: is_nothrow_move_constructible < value_t >:: value && std :: is_nothrow_move_assignable < value_t >:: value && std :: is_nothrow_move_constructible < json_value >:: value && std :: is_nothrow_move_assignable < json_value >:: value ); 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.","title":"nlohmann::basic_json::operator="},{"location":"api/basic_json/operator%3D/#parameters","text":"other (in) value to copy from","title":"Parameters"},{"location":"api/basic_json/operator%3D/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator%3D/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/operator%3D/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/operator%5B%5D/","text":"nlohmann::basic_json:: operator[] \u00b6 // (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 < typename KeyType > reference operator []( KeyType && key ); template < typename KeyType > const_reference operator []( KeyType && key ) const ; // (4) reference operator []( const json_pointer & ptr ); const_reference operator []( const json_pointer & ptr ) const ; Returns a reference to the array element at specified location idx . Returns a reference to the object element with specified key key . The non-const qualified overload takes the key by value. 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. Returns a reference to the element with specified JSON pointer ptr . Template parameters \u00b6 KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17). Parameters \u00b6 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 \u00b6 (const) reference to the element at index idx (const) reference to the element at key key (const) reference to the element at key key (const) reference to the element pointed to by ptr Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 The function can throw the following exceptions: Throws type_error.305 if the JSON value is not an array or null; in that case, using the [] operator with an index makes no sense. The function can throw the following exceptions: Throws type_error.305 if the JSON value is not an object or null; in that case, using the [] operator with a key makes no sense. See 2. The function can throw the following exceptions: Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr for the const version. Throws out_of_range.404 if the JSON pointer ptr can not be resolved. Complexity \u00b6 Constant if idx is in the range of the array. Otherwise, linear in idx - size() . Logarithmic in the size of the container. Logarithmic in the size of the container. Logarithmic in the size of the container. Notes \u00b6 Undefined behavior and runtime assertions If the element with key idx does not exist, the behavior is undefined. If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion ! 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. 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. See 2. 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 \u00b6 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 \u00b6 documentation on unchecked access documentation on runtime assertions see at for access by reference with range checking see value for access with default value Version history \u00b6 Added in version 1.0.0. 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. Added in version 3.11.0. Added in version 2.0.0.","title":"operator[]"},{"location":"api/basic_json/operator%5B%5D/#nlohmannbasic_jsonoperator","text":"// (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 < typename KeyType > reference operator []( KeyType && key ); template < typename KeyType > const_reference operator []( KeyType && key ) const ; // (4) reference operator []( const json_pointer & ptr ); const_reference operator []( const json_pointer & ptr ) const ; Returns a reference to the array element at specified location idx . Returns a reference to the object element with specified key key . The non-const qualified overload takes the key by value. 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. Returns a reference to the element with specified JSON pointer ptr .","title":"nlohmann::basic_json::operator[]"},{"location":"api/basic_json/operator%5B%5D/#template-parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . This can also be a string view (C++17).","title":"Template parameters"},{"location":"api/basic_json/operator%5B%5D/#parameters","text":"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","title":"Parameters"},{"location":"api/basic_json/operator%5B%5D/#return-value","text":"(const) reference to the element at index idx (const) reference to the element at key key (const) reference to the element at key key (const) reference to the element pointed to by ptr","title":"Return value"},{"location":"api/basic_json/operator%5B%5D/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/operator%5B%5D/#exceptions","text":"The function can throw the following exceptions: Throws type_error.305 if the JSON value is not an array or null; in that case, using the [] operator with an index makes no sense. The function can throw the following exceptions: Throws type_error.305 if the JSON value is not an object or null; in that case, using the [] operator with a key makes no sense. See 2. The function can throw the following exceptions: Throws parse_error.106 if an array index in the passed JSON pointer ptr begins with '0'. Throws parse_error.109 if an array index in the passed JSON pointer ptr is not a number. Throws out_of_range.402 if the array index '-' is used in the passed JSON pointer ptr for the const version. Throws out_of_range.404 if the JSON pointer ptr can not be resolved.","title":"Exceptions"},{"location":"api/basic_json/operator%5B%5D/#complexity","text":"Constant if idx is in the range of the array. Otherwise, linear in idx - size() . Logarithmic in the size of the container. Logarithmic in the size of the container. Logarithmic in the size of the container.","title":"Complexity"},{"location":"api/basic_json/operator%5B%5D/#notes","text":"Undefined behavior and runtime assertions If the element with key idx does not exist, the behavior is undefined. If the element with key key does not exist, the behavior is undefined and is guarded by a runtime assertion ! 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. 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. See 2. 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.","title":"Notes"},{"location":"api/basic_json/operator%5B%5D/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/operator%5B%5D/#see-also","text":"documentation on unchecked access documentation on runtime assertions see at for access by reference with range checking see value for access with default value","title":"See also"},{"location":"api/basic_json/operator%5B%5D/#version-history","text":"Added in version 1.0.0. 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. Added in version 3.11.0. Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/operator_ValueType/","text":"nlohmann::basic_json:: operator ValueType \u00b6 template < typename ValueType > JSON_EXPLICIT operator ValueType () const ; Implicit type conversion between the JSON value and a compatible value. The call is realized by calling get() . See Notes for the meaning of JSON_EXPLICIT . Template parameters \u00b6 ValueType the value type to return Return value \u00b6 copy of the JSON value, converted to ValueType Exceptions \u00b6 Depends on what json_serializer from_json() method throws Complexity \u00b6 Linear in the size of the JSON value. Notes \u00b6 Definition of JSON_EXPLICIT By default JSON_EXPLICIT is defined to the empty string, so the signature is: template < typename ValueType > operator ValueType () const ; If JSON_USE_IMPLICIT_CONVERSIONS is set to 0 , JSON_EXPLICIT is defined to explicit : template < typename ValueType > explicit operator ValueType () const ; That is, implicit conversions can be switched off by defining JSON_USE_IMPLICIT_CONVERSIONS 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 to 0 and replace any implicit conversions with calls to get . Examples \u00b6 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 < short > v7 = json_types [ \"array\" ]; std :: unordered_map < std :: string , json > 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 ( json :: type_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: 1 42 42 17.23 17 Hello , world! 1 2 3 4 5 s tr i n g : \"Hello, world!\" nu mber : { \"floating-point\" : 17.23 , \"integer\" : 42 } null : null boolea n : true array : [ 1 , 2 , 3 , 4 , 5 ] [ jso n .excep t io n . t ype_error. 302 ] t ype mus t be boolea n , bu t is s tr i n g Version history \u00b6 Since version 1.0.0. Macros JSON_EXPLICIT / JSON_USE_IMPLICIT_CONVERSIONS added in version 3.9.0.","title":"operator ValueType"},{"location":"api/basic_json/operator_ValueType/#nlohmannbasic_jsonoperator-valuetype","text":"template < typename ValueType > JSON_EXPLICIT operator ValueType () const ; Implicit type conversion between the JSON value and a compatible value. The call is realized by calling get() . See Notes for the meaning of JSON_EXPLICIT .","title":"nlohmann::basic_json::operator ValueType"},{"location":"api/basic_json/operator_ValueType/#template-parameters","text":"ValueType the value type to return","title":"Template parameters"},{"location":"api/basic_json/operator_ValueType/#return-value","text":"copy of the JSON value, converted to ValueType","title":"Return value"},{"location":"api/basic_json/operator_ValueType/#exceptions","text":"Depends on what json_serializer from_json() method throws","title":"Exceptions"},{"location":"api/basic_json/operator_ValueType/#complexity","text":"Linear in the size of the JSON value.","title":"Complexity"},{"location":"api/basic_json/operator_ValueType/#notes","text":"Definition of JSON_EXPLICIT By default JSON_EXPLICIT is defined to the empty string, so the signature is: template < typename ValueType > operator ValueType () const ; If JSON_USE_IMPLICIT_CONVERSIONS is set to 0 , JSON_EXPLICIT is defined to explicit : template < typename ValueType > explicit operator ValueType () const ; That is, implicit conversions can be switched off by defining JSON_USE_IMPLICIT_CONVERSIONS 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 to 0 and replace any implicit conversions with calls to get .","title":"Notes"},{"location":"api/basic_json/operator_ValueType/#examples","text":"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 < short > v7 = json_types [ \"array\" ]; std :: unordered_map < std :: string , json > 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 ( json :: type_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: 1 42 42 17.23 17 Hello , world! 1 2 3 4 5 s tr i n g : \"Hello, world!\" nu mber : { \"floating-point\" : 17.23 , \"integer\" : 42 } null : null boolea n : true array : [ 1 , 2 , 3 , 4 , 5 ] [ jso n .excep t io n . t ype_error. 302 ] t ype mus t be boolea n , bu t is s tr i n g","title":"Examples"},{"location":"api/basic_json/operator_ValueType/#version-history","text":"Since version 1.0.0. Macros JSON_EXPLICIT / JSON_USE_IMPLICIT_CONVERSIONS added in version 3.9.0.","title":"Version history"},{"location":"api/basic_json/operator_eq/","text":"nlohmann::basic_json:: operator== \u00b6 // until C++20 bool operator == ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator == ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > 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 < typename ScalarType > bool operator == ( ScalarType rhs ) const noexcept ; // (2) }; Compares two JSON values for equality according to the following rules: Two JSON values are equal if (1) neither value is discarded, or (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. 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 \u00b6 ScalarType a scalar type according to std::is_scalar::value Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether the values lhs / *this and rhs are equal Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear. Notes \u00b6 Comparing special values NaN values are unordered within the domain of numbers. The following comparisons all yield false : Comparing a NaN with itself. Comparing a NaN with another NaN . 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 could be used, for instance template < typename T , typename = typename std :: enable_if < std :: is_floating_point < T >:: value , T >:: type > inline bool is_same ( T a , T b , T epsilon = std :: numeric_limits < T >:: epsilon ()) noexcept { return std :: abs ( a - b ) <= epsilon ; } Or you can self-defined 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 < float >:: 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 or nlohmann::ordered_json 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 \u00b6 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 ] == null p tr false { \"A\" : \"a\" , \"B\" : \"b\" } == null p tr false 17 == null p tr false \"foo\" == null p tr false null == null p tr true Version history \u00b6 Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.","title":"operator=="},{"location":"api/basic_json/operator_eq/#nlohmannbasic_jsonoperator","text":"// until C++20 bool operator == ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator == ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > 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 < typename ScalarType > bool operator == ( ScalarType rhs ) const noexcept ; // (2) }; Compares two JSON values for equality according to the following rules: Two JSON values are equal if (1) neither value is discarded, or (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. 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.","title":"nlohmann::basic_json::operator=="},{"location":"api/basic_json/operator_eq/#template-parameters","text":"ScalarType a scalar type according to std::is_scalar::value","title":"Template parameters"},{"location":"api/basic_json/operator_eq/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/basic_json/operator_eq/#return-value","text":"whether the values lhs / *this and rhs are equal","title":"Return value"},{"location":"api/basic_json/operator_eq/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_eq/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator_eq/#notes","text":"Comparing special values NaN values are unordered within the domain of numbers. The following comparisons all yield false : Comparing a NaN with itself. Comparing a NaN with another NaN . 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 could be used, for instance template < typename T , typename = typename std :: enable_if < std :: is_floating_point < T >:: value , T >:: type > inline bool is_same ( T a , T b , T epsilon = std :: numeric_limits < T >:: epsilon ()) noexcept { return std :: abs ( a - b ) <= epsilon ; } Or you can self-defined 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 < float >:: 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 or nlohmann::ordered_json 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","title":"Notes"},{"location":"api/basic_json/operator_eq/#examples","text":"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 ] == null p tr false { \"A\" : \"a\" , \"B\" : \"b\" } == null p tr false 17 == null p tr false \"foo\" == null p tr false null == null p tr true","title":"Examples"},{"location":"api/basic_json/operator_eq/#version-history","text":"Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/operator_ge/","text":"nlohmann::basic_json:: operator>= \u00b6 // until C++20 bool operator >= ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator >= ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator >= ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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< ). 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 \u00b6 ScalarType a scalar type according to std::is_scalar::value Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether lhs is less than or equal to rhs Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear. Notes \u00b6 Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> . Examples \u00b6 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 \u00b6 operator<=> comparison: 3-way Version history \u00b6 Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"operator>="},{"location":"api/basic_json/operator_ge/#nlohmannbasic_jsonoperator","text":"// until C++20 bool operator >= ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator >= ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator >= ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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< ). 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.","title":"nlohmann::basic_json::operator>="},{"location":"api/basic_json/operator_ge/#template-parameters","text":"ScalarType a scalar type according to std::is_scalar::value","title":"Template parameters"},{"location":"api/basic_json/operator_ge/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/basic_json/operator_ge/#return-value","text":"whether lhs is less than or equal to rhs","title":"Return value"},{"location":"api/basic_json/operator_ge/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_ge/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator_ge/#notes","text":"Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> .","title":"Notes"},{"location":"api/basic_json/operator_ge/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/operator_ge/#see-also","text":"operator<=> comparison: 3-way","title":"See also"},{"location":"api/basic_json/operator_ge/#version-history","text":"Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/operator_gt/","text":"nlohmann::basic_json:: operator> \u00b6 // until C++20 bool operator > ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator > ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator > ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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<= ). Compares wether 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 \u00b6 ScalarType a scalar type according to std::is_scalar::value Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether lhs is greater than rhs Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear. Notes \u00b6 Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> . Examples \u00b6 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 \u00b6 operator<=> comparison: 3-way Version history \u00b6 Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"operator>"},{"location":"api/basic_json/operator_gt/#nlohmannbasic_jsonoperator","text":"// until C++20 bool operator > ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator > ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator > ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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<= ). Compares wether 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.","title":"nlohmann::basic_json::operator>"},{"location":"api/basic_json/operator_gt/#template-parameters","text":"ScalarType a scalar type according to std::is_scalar::value","title":"Template parameters"},{"location":"api/basic_json/operator_gt/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/basic_json/operator_gt/#return-value","text":"whether lhs is greater than rhs","title":"Return value"},{"location":"api/basic_json/operator_gt/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_gt/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator_gt/#notes","text":"Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> .","title":"Notes"},{"location":"api/basic_json/operator_gt/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/operator_gt/#see-also","text":"operator<=> comparison: 3-way","title":"See also"},{"location":"api/basic_json/operator_gt/#version-history","text":"Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/operator_le/","text":"nlohmann::basic_json:: operator<= \u00b6 // until C++20 bool operator <= ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator <= ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator <= ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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< ). Compares wether 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 \u00b6 ScalarType a scalar type according to std::is_scalar::value Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether lhs is less than or equal to rhs Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear. Notes \u00b6 Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> . Examples \u00b6 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 \u00b6 operator<=> comparison: 3-way Version history \u00b6 Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"operator<="},{"location":"api/basic_json/operator_le/#nlohmannbasic_jsonoperator","text":"// until C++20 bool operator <= ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator <= ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator <= ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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< ). Compares wether 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.","title":"nlohmann::basic_json::operator<="},{"location":"api/basic_json/operator_le/#template-parameters","text":"ScalarType a scalar type according to std::is_scalar::value","title":"Template parameters"},{"location":"api/basic_json/operator_le/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/basic_json/operator_le/#return-value","text":"whether lhs is less than or equal to rhs","title":"Return value"},{"location":"api/basic_json/operator_le/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_le/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator_le/#notes","text":"Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> .","title":"Notes"},{"location":"api/basic_json/operator_le/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/operator_le/#see-also","text":"operator<=> comparison: 3-way","title":"See also"},{"location":"api/basic_json/operator_le/#version-history","text":"Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/operator_lt/","text":"nlohmann::basic_json:: operator< \u00b6 // until C++20 bool operator < ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator < ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator < ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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: null boolean number (all types) object array string binary For instance, any boolean value is considered less than any string. Compares wether 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 \u00b6 ScalarType a scalar type according to std::is_scalar::value Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether lhs is less than rhs Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear. Notes \u00b6 Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> . Examples \u00b6 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 \u00b6 operator<=> comparison: 3-way Version history \u00b6 Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"operator<"},{"location":"api/basic_json/operator_lt/#nlohmannbasic_jsonoperator","text":"// until C++20 bool operator < ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator < ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > bool operator < ( ScalarType lhs , const const_reference rhs ) noexcept ; // (2) 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: null boolean number (all types) object array string binary For instance, any boolean value is considered less than any string. Compares wether 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.","title":"nlohmann::basic_json::operator<"},{"location":"api/basic_json/operator_lt/#template-parameters","text":"ScalarType a scalar type according to std::is_scalar::value","title":"Template parameters"},{"location":"api/basic_json/operator_lt/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/basic_json/operator_lt/#return-value","text":"whether lhs is less than rhs","title":"Return value"},{"location":"api/basic_json/operator_lt/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_lt/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator_lt/#notes","text":"Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator<=> .","title":"Notes"},{"location":"api/basic_json/operator_lt/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/operator_lt/#see-also","text":"operator<=> comparison: 3-way","title":"See also"},{"location":"api/basic_json/operator_lt/#version-history","text":"Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0. Added in version 1.0.0. Conditionally removed since C++20 in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/operator_ne/","text":"nlohmann::basic_json:: operator!= \u00b6 // until C++20 bool operator != ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator != ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > 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 < typename ScalarType > bool operator != ( ScalarType rhs ) const noexcept ; // (2) }; 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). 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 \u00b6 ScalarType a scalar type according to std::is_scalar::value Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether the values lhs / *this and rhs are not equal Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear. Notes \u00b6 Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number. Examples \u00b6 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 ] != null p tr true { \"A\" : \"a\" , \"B\" : \"b\" } != null p tr true 17 != null p tr true \"foo\" != null p tr true null != null p tr false Version history \u00b6 Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.","title":"operator!="},{"location":"api/basic_json/operator_ne/#nlohmannbasic_jsonoperator","text":"// until C++20 bool operator != ( const_reference lhs , const_reference rhs ) noexcept ; // (1) template < typename ScalarType > bool operator != ( const_reference lhs , const ScalarType rhs ) noexcept ; // (2) template < typename ScalarType > 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 < typename ScalarType > bool operator != ( ScalarType rhs ) const noexcept ; // (2) }; 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). 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.","title":"nlohmann::basic_json::operator!="},{"location":"api/basic_json/operator_ne/#template-parameters","text":"ScalarType a scalar type according to std::is_scalar::value","title":"Template parameters"},{"location":"api/basic_json/operator_ne/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/basic_json/operator_ne/#return-value","text":"whether the values lhs / *this and rhs are not equal","title":"Return value"},{"location":"api/basic_json/operator_ne/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_ne/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator_ne/#notes","text":"Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield false : 1. Comparing a NaN with itself. 2. Comparing a NaN with another NaN . 3. Comparing a NaN and any other number.","title":"Notes"},{"location":"api/basic_json/operator_ne/#examples","text":"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 ] != null p tr true { \"A\" : \"a\" , \"B\" : \"b\" } != null p tr true 17 != null p tr true \"foo\" != null p tr true null != null p tr false","title":"Examples"},{"location":"api/basic_json/operator_ne/#version-history","text":"Added in version 1.0.0. Added C++20 member functions in version 3.11.0. Added in version 1.0.0. Added C++20 member functions in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/operator_spaceship/","text":"nlohmann::basic_json:: operator<=> \u00b6 // since C++20 class basic_json { std :: partial_ordering operator <=> ( const_reference rhs ) const noexcept ; // (1) template < typename ScalarType > std :: partial_ordering operator <=> ( const ScalarType rhs ) const noexcept ; // (2) }; 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 ). 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 \u00b6 ScalarType a scalar type according to std::is_scalar::value Parameters \u00b6 rhs (in) second value to consider Return value \u00b6 the std::partial_ordering of the 3-way comparison of *this and rhs Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Linear. Notes \u00b6 Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield std::partial_ordering::unordered : Comparing a NaN with itself. Comparing a NaN with another NaN . Comparing a NaN and any other number. Examples \u00b6 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\" } : = equivale nt \"foo\" <=> 17 : = grea ter \"foo\" <=> : = u n ordered 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 < json :: number_float_t > ; 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 : = equivale nt 17 <=> nan : = u n ordered \"17\" <=> 17 : = grea ter See also \u00b6 operator== - comparison: equal operator!= - comparison: not equal operator< - comparison: less than operator<= - comparison: less than or equal operator> - comparison: greater than operator>= - comparison: greater than or equal Version history \u00b6 Added in version 3.11.0. Added in version 3.11.0.","title":"operator<=>"},{"location":"api/basic_json/operator_spaceship/#nlohmannbasic_jsonoperator","text":"// since C++20 class basic_json { std :: partial_ordering operator <=> ( const_reference rhs ) const noexcept ; // (1) template < typename ScalarType > std :: partial_ordering operator <=> ( const ScalarType rhs ) const noexcept ; // (2) }; 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 ). 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).","title":"nlohmann::basic_json::operator<=>"},{"location":"api/basic_json/operator_spaceship/#template-parameters","text":"ScalarType a scalar type according to std::is_scalar::value","title":"Template parameters"},{"location":"api/basic_json/operator_spaceship/#parameters","text":"rhs (in) second value to consider","title":"Parameters"},{"location":"api/basic_json/operator_spaceship/#return-value","text":"the std::partial_ordering of the 3-way comparison of *this and rhs","title":"Return value"},{"location":"api/basic_json/operator_spaceship/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_spaceship/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/operator_spaceship/#notes","text":"Comparing NaN NaN values are unordered within the domain of numbers. The following comparisons all yield std::partial_ordering::unordered : Comparing a NaN with itself. Comparing a NaN with another NaN . Comparing a NaN and any other number.","title":"Notes"},{"location":"api/basic_json/operator_spaceship/#examples","text":"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\" } : = equivale nt \"foo\" <=> 17 : = grea ter \"foo\" <=> : = u n ordered 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 < json :: number_float_t > ; 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 : = equivale nt 17 <=> nan : = u n ordered \"17\" <=> 17 : = grea ter","title":"Examples"},{"location":"api/basic_json/operator_spaceship/#see-also","text":"operator== - comparison: equal operator!= - comparison: not equal operator< - comparison: less than operator<= - comparison: less than or equal operator> - comparison: greater than operator>= - comparison: greater than or equal","title":"See also"},{"location":"api/basic_json/operator_spaceship/#version-history","text":"Added in version 3.11.0. Added in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/operator_value_t/","text":"nlohmann::basic_json:: operator value_t \u00b6 constexpr operator value_t () const noexcept ; Return the type of the JSON value as a value from the value_t enumeration. Return value \u00b6 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 \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0. Added unsigned integer type in version 2.0.0. Added binary type in version 3.8.0.","title":"operator value_t"},{"location":"api/basic_json/operator_value_t/#nlohmannbasic_jsonoperator-value_t","text":"constexpr operator value_t () const noexcept ; Return the type of the JSON value as a value from the value_t enumeration.","title":"nlohmann::basic_json::operator value_t"},{"location":"api/basic_json/operator_value_t/#return-value","text":"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","title":"Return value"},{"location":"api/basic_json/operator_value_t/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/operator_value_t/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/operator_value_t/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/operator_value_t/#version-history","text":"Added in version 1.0.0. Added unsigned integer type in version 2.0.0. Added binary type in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/other_error/","text":"nlohmann::basic_json:: other_error \u00b6 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 ). Member functions \u00b6 what - returns explanatory string Member variables \u00b6 id - the id of the exception Examples \u00b6 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 ( json :: other_error & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .o t her_error. 501 ] u nsu ccess ful : { \"op\" : \"test\" , \"path\" : \"/best_biscuit/name\" , \"value\" : \"Choco Leibniz\" } excep t io n id : 501 See also \u00b6 List of other errors parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range Version history \u00b6 Since version 3.0.0.","title":"other_error"},{"location":"api/basic_json/other_error/#nlohmannbasic_jsonother_error","text":"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 ).","title":"nlohmann::basic_json::other_error"},{"location":"api/basic_json/other_error/#member-functions","text":"what - returns explanatory string","title":"Member functions"},{"location":"api/basic_json/other_error/#member-variables","text":"id - the id of the exception","title":"Member variables"},{"location":"api/basic_json/other_error/#examples","text":"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 ( json :: other_error & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .o t her_error. 501 ] u nsu ccess ful : { \"op\" : \"test\" , \"path\" : \"/best_biscuit/name\" , \"value\" : \"Choco Leibniz\" } excep t io n id : 501","title":"Examples"},{"location":"api/basic_json/other_error/#see-also","text":"List of other errors parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range","title":"See also"},{"location":"api/basic_json/other_error/#version-history","text":"Since version 3.0.0.","title":"Version history"},{"location":"api/basic_json/out_of_range/","text":"nlohmann::basic_json:: out_of_range \u00b6 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 case of array indices or nonexisting object keys. Exceptions have ids 4xx (see list of out-of-range errors ). Member functions \u00b6 what - returns explanatory string Member variables \u00b6 id - the id of the exception Examples \u00b6 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 ( json :: out_of_range & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 4 is ou t o f ra n ge excep t io n id : 401 See also \u00b6 List of out-of-range errors parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type other_error for exceptions indicating other library errors Version history \u00b6 Since version 3.0.0.","title":"out_of_range"},{"location":"api/basic_json/out_of_range/#nlohmannbasic_jsonout_of_range","text":"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 case of array indices or nonexisting object keys. Exceptions have ids 4xx (see list of out-of-range errors ).","title":"nlohmann::basic_json::out_of_range"},{"location":"api/basic_json/out_of_range/#member-functions","text":"what - returns explanatory string","title":"Member functions"},{"location":"api/basic_json/out_of_range/#member-variables","text":"id - the id of the exception","title":"Member variables"},{"location":"api/basic_json/out_of_range/#examples","text":"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 ( json :: out_of_range & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n .ou t _o f _ra n ge. 401 ] array i n dex 4 is ou t o f ra n ge excep t io n id : 401","title":"Examples"},{"location":"api/basic_json/out_of_range/#see-also","text":"List of out-of-range errors parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type other_error for exceptions indicating other library errors","title":"See also"},{"location":"api/basic_json/out_of_range/#version-history","text":"Since version 3.0.0.","title":"Version history"},{"location":"api/basic_json/parse/","text":"nlohmann::basic_json:: parse \u00b6 // (1) template < typename InputType > static basic_json parse ( InputType && i , const parser_callback_t cb = nullptr , const bool allow_exceptions = true , const bool ignore_comments = false ); // (2) template < typename IteratorType > static basic_json parse ( IteratorType first , IteratorType last , const parser_callback_t cb = nullptr , const bool allow_exceptions = true , const bool ignore_comments = false ); Deserialize from a compatible input. 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 \u00b6 InputType A compatible input, for instance: an std::istream object a FILE pointer (must not be null) a C-style array of characters a pointer to a null-terminated string of single byte characters 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 \u00b6 i (in) Input to parse from. cb (in) a parser callback function of type parser_callback_t 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) first (in) iterator to start of character range last (in) iterator to end of character range Return value \u00b6 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 . Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws parse_error.101 in case of an unexpected token. Throws parse_error.102 if to_unicode fails or surrogate error. Throws parse_error.103 if to_unicode fails. Complexity \u00b6 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 \u00b6 (1) A UTF-8 byte order mark is silently ignored. Runtime assertion The precondition that a passed FILE pointer must not be null is enforced with a runtime assertion . Examples \u00b6 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 < std :: uint8_t > 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 < std :: uint8_t > 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 \u00b4parse()` 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 ( 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: [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 4 , colum n 0 : sy nta x error while parsi n g value - i n valid s tr i n g : co ntr ol charac ter U+ 000 A (LF) mus t be escaped t o \\u 000 A or \\ n ; las t read : '\"value without closing quotes' the input is invalid JSON See also \u00b6 accept - check if the input is valid JSON operator>> - deserialize from stream Version history \u00b6 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. 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.","title":"parse"},{"location":"api/basic_json/parse/#nlohmannbasic_jsonparse","text":"// (1) template < typename InputType > static basic_json parse ( InputType && i , const parser_callback_t cb = nullptr , const bool allow_exceptions = true , const bool ignore_comments = false ); // (2) template < typename IteratorType > static basic_json parse ( IteratorType first , IteratorType last , const parser_callback_t cb = nullptr , const bool allow_exceptions = true , const bool ignore_comments = false ); Deserialize from a compatible input. 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.","title":"nlohmann::basic_json::parse"},{"location":"api/basic_json/parse/#template-parameters","text":"InputType A compatible input, for instance: an std::istream object a FILE pointer (must not be null) a C-style array of characters a pointer to a null-terminated string of single byte characters 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","title":"Template parameters"},{"location":"api/basic_json/parse/#parameters","text":"i (in) Input to parse from. cb (in) a parser callback function of type parser_callback_t 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) first (in) iterator to start of character range last (in) iterator to end of character range","title":"Parameters"},{"location":"api/basic_json/parse/#return-value","text":"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 .","title":"Return value"},{"location":"api/basic_json/parse/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/parse/#exceptions","text":"Throws parse_error.101 in case of an unexpected token. Throws parse_error.102 if to_unicode fails or surrogate error. Throws parse_error.103 if to_unicode fails.","title":"Exceptions"},{"location":"api/basic_json/parse/#complexity","text":"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.","title":"Complexity"},{"location":"api/basic_json/parse/#notes","text":"(1) A UTF-8 byte order mark is silently ignored. Runtime assertion The precondition that a passed FILE pointer must not be null is enforced with a runtime assertion .","title":"Notes"},{"location":"api/basic_json/parse/#examples","text":"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 < std :: uint8_t > 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 < std :: uint8_t > 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 \u00b4parse()` 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 ( 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: [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 4 , colum n 0 : sy nta x error while parsi n g value - i n valid s tr i n g : co ntr ol charac ter U+ 000 A (LF) mus t be escaped t o \\u 000 A or \\ n ; las t read : '\"value without closing quotes' the input is invalid JSON","title":"Examples"},{"location":"api/basic_json/parse/#see-also","text":"accept - check if the input is valid JSON operator>> - deserialize from stream","title":"See also"},{"location":"api/basic_json/parse/#version-history","text":"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. 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.","title":"Version history"},{"location":"api/basic_json/parse_error/","text":"nlohmann::basic_json:: parse_error \u00b6 class parse_error : public exception ; This exception is thrown by the library 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 ). Member functions \u00b6 what - returns explanatory string Member variables \u00b6 id - the id of the exception byte - byte index of the parse error Notes \u00b6 For an input with n n bytes, 1 is the index of the first character and n+1 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 \u00b6 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 ( 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 : [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 1 , colum n 8 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d ' [ ' , ' { ' , or a li teral excep t io n id : 101 by te posi t io n o f error : 8 See also \u00b6 List of parse errors invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors Version history \u00b6 Since version 3.0.0.","title":"parse_error"},{"location":"api/basic_json/parse_error/#nlohmannbasic_jsonparse_error","text":"class parse_error : public exception ; This exception is thrown by the library 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 ).","title":"nlohmann::basic_json::parse_error"},{"location":"api/basic_json/parse_error/#member-functions","text":"what - returns explanatory string","title":"Member functions"},{"location":"api/basic_json/parse_error/#member-variables","text":"id - the id of the exception byte - byte index of the parse error","title":"Member variables"},{"location":"api/basic_json/parse_error/#notes","text":"For an input with n n bytes, 1 is the index of the first character and n+1 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.","title":"Notes"},{"location":"api/basic_json/parse_error/#examples","text":"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 ( 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 : [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 1 , colum n 8 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d ' [ ' , ' { ' , or a li teral excep t io n id : 101 by te posi t io n o f error : 8","title":"Examples"},{"location":"api/basic_json/parse_error/#see-also","text":"List of parse errors invalid_iterator for exceptions indicating errors with iterators type_error for exceptions indicating executing a member function with a wrong type out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors","title":"See also"},{"location":"api/basic_json/parse_error/#version-history","text":"Since version 3.0.0.","title":"Version history"},{"location":"api/basic_json/parse_event_t/","text":"nlohmann::basic_json:: parse_event_t \u00b6 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 \u00b6 Version history \u00b6 Added in version 1.0.0.","title":"parse_event_t"},{"location":"api/basic_json/parse_event_t/#nlohmannbasic_jsonparse_event_t","text":"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","title":"nlohmann::basic_json::parse_event_t"},{"location":"api/basic_json/parse_event_t/#examples","text":"","title":"Examples"},{"location":"api/basic_json/parse_event_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/parser_callback_t/","text":"nlohmann::basic_json:: parser_callback_t \u00b6 template < typename BasicJsonType > using parser_callback_t = std :: function < bool ( int depth , parse_event_t event , BasicJsonType & parsed ) > ; 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. 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 \u00b6 depth (in) the depth of the recursion during parsing event (in) an event of type parse_event_t 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 \u00b6 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 \u00b6 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 } } Version history \u00b6 Added in version 1.0.0.","title":"parser_callback_t"},{"location":"api/basic_json/parser_callback_t/#nlohmannbasic_jsonparser_callback_t","text":"template < typename BasicJsonType > using parser_callback_t = std :: function < bool ( int depth , parse_event_t event , BasicJsonType & parsed ) > ; 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. 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.","title":"nlohmann::basic_json::parser_callback_t"},{"location":"api/basic_json/parser_callback_t/#parameters","text":"depth (in) the depth of the recursion during parsing event (in) an event of type parse_event_t 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","title":"Parameters"},{"location":"api/basic_json/parser_callback_t/#return-value","text":"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.","title":"Return value"},{"location":"api/basic_json/parser_callback_t/#examples","text":"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 } }","title":"Examples"},{"location":"api/basic_json/parser_callback_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/patch/","text":"nlohmann::basic_json:: patch \u00b6 basic_json patch ( const basic_json & json_patch ) const ; JSON Patch 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 \u00b6 json_patch (in) JSON patch document Return value \u00b6 patched document Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Exceptions \u00b6 Throws parse_error.104 if the JSON patch does not consist of an array of objects. Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation add must have member path\" . Throws out_of_range.401 if an array index is out of range. Throws out_of_range.403 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 if JSON pointer has no parent (\"add\", \"remove\", \"move\") Throws out_of_range.501 if \"test\" operation was unsuccessful. Complexity \u00b6 Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is affected by the patch, the complexity can usually be neglected. Notes \u00b6 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 \u00b6 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 \u00b6 RFC 6902 (JSON Patch) RFC 6901 (JSON Pointer) patch_inplace applies a JSON Patch without creating a copy of the document merge_patch applies a JSON Merge Patch Version history \u00b6 Added in version 2.0.0.","title":"patch"},{"location":"api/basic_json/patch/#nlohmannbasic_jsonpatch","text":"basic_json patch ( const basic_json & json_patch ) const ; JSON Patch 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.","title":"nlohmann::basic_json::patch"},{"location":"api/basic_json/patch/#parameters","text":"json_patch (in) JSON patch document","title":"Parameters"},{"location":"api/basic_json/patch/#return-value","text":"patched document","title":"Return value"},{"location":"api/basic_json/patch/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/patch/#exceptions","text":"Throws parse_error.104 if the JSON patch does not consist of an array of objects. Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation add must have member path\" . Throws out_of_range.401 if an array index is out of range. Throws out_of_range.403 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 if JSON pointer has no parent (\"add\", \"remove\", \"move\") Throws out_of_range.501 if \"test\" operation was unsuccessful.","title":"Exceptions"},{"location":"api/basic_json/patch/#complexity","text":"Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is affected by the patch, the complexity can usually be neglected.","title":"Complexity"},{"location":"api/basic_json/patch/#notes","text":"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.","title":"Notes"},{"location":"api/basic_json/patch/#examples","text":"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\" ] }","title":"Examples"},{"location":"api/basic_json/patch/#see-also","text":"RFC 6902 (JSON Patch) RFC 6901 (JSON Pointer) patch_inplace applies a JSON Patch without creating a copy of the document merge_patch applies a JSON Merge Patch","title":"See also"},{"location":"api/basic_json/patch/#version-history","text":"Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/patch_inplace/","text":"nlohmann::basic_json:: patch_inplace \u00b6 void patch_inplace ( const basic_json & json_patch ) const ; JSON Patch 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 \u00b6 json_patch (in) JSON patch document Exception safety \u00b6 No guarantees, value may be corrupted by an unsuccessful patch operation. Exceptions \u00b6 Throws parse_error.104 if the JSON patch does not consist of an array of objects. Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation add must have member path\" . Throws out_of_range.401 if an array index is out of range. Throws out_of_range.403 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 if JSON pointer has no parent (\"add\", \"remove\", \"move\") Throws out_of_range.501 if \"test\" operation was unsuccessful. Complexity \u00b6 Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is affected by the patch, the complexity can usually be neglected. Notes \u00b6 Unlike patch , 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 \u00b6 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 << \" \\n After \\n \" << std :: setw ( 4 ) << doc << std :: endl ; } Output: Be f ore { \"baz\" : \"qux\" , \"foo\" : \"bar\" } A fter { \"baz\" : \"boo\" , \"hello\" : [ \"world\" ] } See also \u00b6 RFC 6902 (JSON Patch) RFC 6901 (JSON Pointer) patch applies a JSON Merge Patch merge_patch applies a JSON Merge Patch Version history \u00b6 Added in version 3.11.0.","title":"patch_inplace"},{"location":"api/basic_json/patch_inplace/#nlohmannbasic_jsonpatch_inplace","text":"void patch_inplace ( const basic_json & json_patch ) const ; JSON Patch 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.","title":"nlohmann::basic_json::patch_inplace"},{"location":"api/basic_json/patch_inplace/#parameters","text":"json_patch (in) JSON patch document","title":"Parameters"},{"location":"api/basic_json/patch_inplace/#exception-safety","text":"No guarantees, value may be corrupted by an unsuccessful patch operation.","title":"Exception safety"},{"location":"api/basic_json/patch_inplace/#exceptions","text":"Throws parse_error.104 if the JSON patch does not consist of an array of objects. Throws parse_error.105 if the JSON patch is malformed (e.g., mandatory attributes are missing); example: \"operation add must have member path\" . Throws out_of_range.401 if an array index is out of range. Throws out_of_range.403 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 if JSON pointer has no parent (\"add\", \"remove\", \"move\") Throws out_of_range.501 if \"test\" operation was unsuccessful.","title":"Exceptions"},{"location":"api/basic_json/patch_inplace/#complexity","text":"Linear in the size of the JSON value and the length of the JSON patch. As usually only a fraction of the JSON value is affected by the patch, the complexity can usually be neglected.","title":"Complexity"},{"location":"api/basic_json/patch_inplace/#notes","text":"Unlike patch , 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.","title":"Notes"},{"location":"api/basic_json/patch_inplace/#examples","text":"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 << \" \\n After \\n \" << std :: setw ( 4 ) << doc << std :: endl ; } Output: Be f ore { \"baz\" : \"qux\" , \"foo\" : \"bar\" } A fter { \"baz\" : \"boo\" , \"hello\" : [ \"world\" ] }","title":"Examples"},{"location":"api/basic_json/patch_inplace/#see-also","text":"RFC 6902 (JSON Patch) RFC 6901 (JSON Pointer) patch applies a JSON Merge Patch merge_patch applies a JSON Merge Patch","title":"See also"},{"location":"api/basic_json/patch_inplace/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/push_back/","text":"nlohmann::basic_json:: push_back \u00b6 // (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 ); 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 . 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 . This function allows using push_back with an initializer list. In case the current value is an object, the initializer list init contains only two elements, and 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&&) . Parameters \u00b6 val (in) the value to add to the JSON array/object init (in) an initializer list Exceptions \u00b6 All functions can throw the following exception: - Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\" Complexity \u00b6 Amortized constant. Logarithmic in the size of the container, O(log( size() )). Linear in the size of the initializer list init . Notes \u00b6 (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 for more information. Examples \u00b6 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 ]] Version history \u00b6 Since version 1.0.0. Since version 1.0.0. Since version 2.0.0.","title":"push_back"},{"location":"api/basic_json/push_back/#nlohmannbasic_jsonpush_back","text":"// (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 ); 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 . 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 . This function allows using push_back with an initializer list. In case the current value is an object, the initializer list init contains only two elements, and 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&&) .","title":"nlohmann::basic_json::push_back"},{"location":"api/basic_json/push_back/#parameters","text":"val (in) the value to add to the JSON array/object init (in) an initializer list","title":"Parameters"},{"location":"api/basic_json/push_back/#exceptions","text":"All functions can throw the following exception: - Throws type_error.308 when called on a type other than JSON array or null; example: \"cannot use push_back() with number\"","title":"Exceptions"},{"location":"api/basic_json/push_back/#complexity","text":"Amortized constant. Logarithmic in the size of the container, O(log( size() )). Linear in the size of the initializer list init .","title":"Complexity"},{"location":"api/basic_json/push_back/#notes","text":"(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 for more information.","title":"Notes"},{"location":"api/basic_json/push_back/#examples","text":"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 ]]","title":"Examples"},{"location":"api/basic_json/push_back/#version-history","text":"Since version 1.0.0. Since version 1.0.0. Since version 2.0.0.","title":"Version history"},{"location":"api/basic_json/rbegin/","text":"nlohmann::basic_json:: rbegin \u00b6 reverse_iterator rbegin () noexcept ; const_reverse_iterator rbegin () const noexcept ; Returns an iterator to the reverse-beginning; that is, the last element. Return value \u00b6 reverse iterator to the first element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0.","title":"rbegin"},{"location":"api/basic_json/rbegin/#nlohmannbasic_jsonrbegin","text":"reverse_iterator rbegin () noexcept ; const_reverse_iterator rbegin () const noexcept ; Returns an iterator to the reverse-beginning; that is, the last element.","title":"nlohmann::basic_json::rbegin"},{"location":"api/basic_json/rbegin/#return-value","text":"reverse iterator to the first element","title":"Return value"},{"location":"api/basic_json/rbegin/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/rbegin/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/rbegin/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/rbegin/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/rend/","text":"nlohmann::basic_json:: rend \u00b6 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 \u00b6 reverse iterator to the element following the last element Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 Example The following code shows an example for eend() . #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 \u00b6 Added in version 1.0.0.","title":"rend"},{"location":"api/basic_json/rend/#nlohmannbasic_jsonrend","text":"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.","title":"nlohmann::basic_json::rend"},{"location":"api/basic_json/rend/#return-value","text":"reverse iterator to the element following the last element","title":"Return value"},{"location":"api/basic_json/rend/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/rend/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/rend/#examples","text":"Example The following code shows an example for eend() . #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","title":"Examples"},{"location":"api/basic_json/rend/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/sax_parse/","text":"nlohmann::basic_json:: sax_parse \u00b6 // (1) template < typename InputType , typename SAX > 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 ); // (2) template < class IteratorType , class SAX > 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 ); Read from input and generate SAX events Read from a compatible input. Read 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. The SAX event lister must follow the interface of json_sax . Template parameters \u00b6 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 Description SAX Description Parameters \u00b6 i (in) Input to parse from. sax (in) SAX event listener format (in) the format to parse (JSON, CBOR, MessagePack, or UBJSON) (optional, input_format_t::json by default), see input_format_t 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) first (in) iterator to start of character range last (in) iterator to end of character range Return value \u00b6 return value of the last processed SAX event Exception safety \u00b6 Complexity \u00b6 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 \u00b6 A UTF-8 byte order mark is silently ignored. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0. Ignoring comments via ignore_comments added in version 3.9.0. 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 ); .","title":"sax_parse"},{"location":"api/basic_json/sax_parse/#nlohmannbasic_jsonsax_parse","text":"// (1) template < typename InputType , typename SAX > 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 ); // (2) template < class IteratorType , class SAX > 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 ); Read from input and generate SAX events Read from a compatible input. Read 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. The SAX event lister must follow the interface of json_sax .","title":"nlohmann::basic_json::sax_parse"},{"location":"api/basic_json/sax_parse/#template-parameters","text":"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 Description SAX Description","title":"Template parameters"},{"location":"api/basic_json/sax_parse/#parameters","text":"i (in) Input to parse from. sax (in) SAX event listener format (in) the format to parse (JSON, CBOR, MessagePack, or UBJSON) (optional, input_format_t::json by default), see input_format_t 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) first (in) iterator to start of character range last (in) iterator to end of character range","title":"Parameters"},{"location":"api/basic_json/sax_parse/#return-value","text":"return value of the last processed SAX event","title":"Return value"},{"location":"api/basic_json/sax_parse/#exception-safety","text":"","title":"Exception safety"},{"location":"api/basic_json/sax_parse/#complexity","text":"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.","title":"Complexity"},{"location":"api/basic_json/sax_parse/#notes","text":"A UTF-8 byte order mark is silently ignored.","title":"Notes"},{"location":"api/basic_json/sax_parse/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/basic_json/sax_parse/#version-history","text":"Added in version 3.2.0. Ignoring comments via ignore_comments added in version 3.9.0. 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 ); .","title":"Version history"},{"location":"api/basic_json/size/","text":"nlohmann::basic_json:: size \u00b6 size_type size () const noexcept ; Returns the number of elements in a JSON value. Return value \u00b6 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 \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant, as long as array_t and object_t satisfy the Container concept; that is, their size() functions have constant complexity. Notes \u00b6 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 \u00b6 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 \u00b6 Added in version 1.0.0. Extended to return 1 for binary types in version 3.8.0.","title":"size"},{"location":"api/basic_json/size/#nlohmannbasic_jsonsize","text":"size_type size () const noexcept ; Returns the number of elements in a JSON value.","title":"nlohmann::basic_json::size"},{"location":"api/basic_json/size/#return-value","text":"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()","title":"Return value"},{"location":"api/basic_json/size/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/size/#complexity","text":"Constant, as long as array_t and object_t satisfy the Container concept; that is, their size() functions have constant complexity.","title":"Complexity"},{"location":"api/basic_json/size/#notes","text":"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.","title":"Notes"},{"location":"api/basic_json/size/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/size/#version-history","text":"Added in version 1.0.0. Extended to return 1 for binary types in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/std_hash/","text":"std:: hash \u00b6 namespace std { struct hash < nlohmann :: basic_json > ; } 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 \u00b6 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 > {}( json ( nullptr )) << '\\n' << \"hash(false) = \" << std :: hash < json > {}( json ( false )) << '\\n' << \"hash(0) = \" << std :: hash < json > {}( json ( 0 )) << '\\n' << \"hash(0U) = \" << std :: hash < json > {}( json ( 0U )) << '\\n' << \"hash( \\\"\\\" ) = \" << std :: hash < json > {}( json ( \"\" )) << '\\n' << \"hash({}) = \" << std :: hash < json > {}( json :: object ()) << '\\n' << \"hash([]) = \" << std :: hash < json > {}( json :: array ()) << '\\n' << \"hash({ \\\" hello \\\" : \\\" world \\\" }) = \" << std :: hash < json > {}( \"{ \\\" hello \\\" : \\\" world \\\" }\" _json ) << std :: endl ; } Output: hash( null ) = 2654435769 hash( false ) = 2654436030 hash( 0 ) = 2654436095 hash( 0 U) = 2654436156 hash( \"\" ) = 6142509191626859748 hash( {} ) = 2654435832 hash( [] ) = 2654435899 hash( { \"hello\" : \"world\" } ) = 4469488738203676328 Note the output is platform-dependent. Version history \u00b6 Added in version 1.0.0. Extended for arbitrary basic_json types in version 3.10.5.","title":"std::hash<basic_json>"},{"location":"api/basic_json/std_hash/#stdhashnlohmannbasic_json","text":"namespace std { struct hash < nlohmann :: basic_json > ; } 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.","title":"std::hash<nlohmann::basic_json>"},{"location":"api/basic_json/std_hash/#examples","text":"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 > {}( json ( nullptr )) << '\\n' << \"hash(false) = \" << std :: hash < json > {}( json ( false )) << '\\n' << \"hash(0) = \" << std :: hash < json > {}( json ( 0 )) << '\\n' << \"hash(0U) = \" << std :: hash < json > {}( json ( 0U )) << '\\n' << \"hash( \\\"\\\" ) = \" << std :: hash < json > {}( json ( \"\" )) << '\\n' << \"hash({}) = \" << std :: hash < json > {}( json :: object ()) << '\\n' << \"hash([]) = \" << std :: hash < json > {}( json :: array ()) << '\\n' << \"hash({ \\\" hello \\\" : \\\" world \\\" }) = \" << std :: hash < json > {}( \"{ \\\" hello \\\" : \\\" world \\\" }\" _json ) << std :: endl ; } Output: hash( null ) = 2654435769 hash( false ) = 2654436030 hash( 0 ) = 2654436095 hash( 0 U) = 2654436156 hash( \"\" ) = 6142509191626859748 hash( {} ) = 2654435832 hash( [] ) = 2654435899 hash( { \"hello\" : \"world\" } ) = 4469488738203676328 Note the output is platform-dependent.","title":"Examples"},{"location":"api/basic_json/std_hash/#version-history","text":"Added in version 1.0.0. Extended for arbitrary basic_json types in version 3.10.5.","title":"Version history"},{"location":"api/basic_json/std_swap/","text":"std::swap \u00b6 namespace std { void swap ( nlohmann :: basic_json & j1 , nlohmann :: basic_json & j2 ); } Exchanges the values of two JSON objects. Parameters \u00b6 j1 (in, out) value to be replaced by j2 j2 (in, out) value to be replaced by j1 Possible implementation \u00b6 void swap ( nlohmann :: basic_json & j1 , nlohmann :: basic_json & j2 ) { j1 . swap ( j2 ); } Examples \u00b6 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: j 1 = { \"one\" : 1 , \"two\" : 2 } | j 2 = [ 1 , 2 , 4 , 8 , 16 ] j 1 = [ 1 , 2 , 4 , 8 , 16 ] | j 2 = { \"one\" : 1 , \"two\" : 2 } See also \u00b6 swap Version history \u00b6 Added in version 1.0.0. Extended for arbitrary basic_json types in version 3.10.5.","title":"std::swap<basic_json>"},{"location":"api/basic_json/std_swap/#stdswapbasic_json","text":"namespace std { void swap ( nlohmann :: basic_json & j1 , nlohmann :: basic_json & j2 ); } Exchanges the values of two JSON objects.","title":"std::swap<basic_json>"},{"location":"api/basic_json/std_swap/#parameters","text":"j1 (in, out) value to be replaced by j2 j2 (in, out) value to be replaced by j1","title":"Parameters"},{"location":"api/basic_json/std_swap/#possible-implementation","text":"void swap ( nlohmann :: basic_json & j1 , nlohmann :: basic_json & j2 ) { j1 . swap ( j2 ); }","title":"Possible implementation"},{"location":"api/basic_json/std_swap/#examples","text":"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: j 1 = { \"one\" : 1 , \"two\" : 2 } | j 2 = [ 1 , 2 , 4 , 8 , 16 ] j 1 = [ 1 , 2 , 4 , 8 , 16 ] | j 2 = { \"one\" : 1 , \"two\" : 2 }","title":"Examples"},{"location":"api/basic_json/std_swap/#see-also","text":"swap","title":"See also"},{"location":"api/basic_json/std_swap/#version-history","text":"Added in version 1.0.0. Extended for arbitrary basic_json types in version 3.10.5.","title":"Version history"},{"location":"api/basic_json/string_t/","text":"nlohmann::basic_json:: string_t \u00b6 using string_t = StringType ; The type used to store JSON strings. RFC 8259 describes JSON strings as follows: A string is a sequence of zero or more Unicode characters. To store objects 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 \u00b6 StringType the container to store strings (e.g., std::string ). Note this container is used for keys/names in objects, see object_t . Notes \u00b6 Default type \u00b6 With the default values for StringType ( std::string ), the default value for string_t is std :: string . Encoding \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 < std :: string , json :: string_t >:: value << std :: endl ; } Output: true Version history \u00b6 Added in version 1.0.0.","title":"string_t"},{"location":"api/basic_json/string_t/#nlohmannbasic_jsonstring_t","text":"using string_t = StringType ; The type used to store JSON strings. RFC 8259 describes JSON strings as follows: A string is a sequence of zero or more Unicode characters. To store objects 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.","title":"nlohmann::basic_json::string_t"},{"location":"api/basic_json/string_t/#template-parameters","text":"StringType the container to store strings (e.g., std::string ). Note this container is used for keys/names in objects, see object_t .","title":"Template parameters"},{"location":"api/basic_json/string_t/#notes","text":"","title":"Notes"},{"location":"api/basic_json/string_t/#default-type","text":"With the default values for StringType ( std::string ), the default value for string_t is std :: string .","title":"Default type"},{"location":"api/basic_json/string_t/#encoding","text":"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.","title":"Encoding"},{"location":"api/basic_json/string_t/#string-comparison","text":"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.","title":"String comparison"},{"location":"api/basic_json/string_t/#storage","text":"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.","title":"Storage"},{"location":"api/basic_json/string_t/#examples","text":"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 < std :: string , json :: string_t >:: value << std :: endl ; } Output: true","title":"Examples"},{"location":"api/basic_json/string_t/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/basic_json/swap/","text":"nlohmann::basic_json:: swap \u00b6 // (1) void swap ( reference other ) noexcept ; // (2) void swap ( reference left , reference right ) noexcept ; // (3) void swap ( array_t & other ); // (4) void swap ( object_t & other ); // (5) void swap ( string_t & other ); // (6) void swap ( binary_t & other ); // (7) void swap ( typename binary_t :: container_type & other ); Exchanges the contents of the JSON value with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. 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. Exchanges the contents of a JSON array with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a JSON object with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a JSON string with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a binary value with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a binary value with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Unlike version (6), no binary subtype is involved. Parameters \u00b6 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 \u00b6 No-throw guarantee: this function never throws exceptions. No-throw guarantee: this function never throws exceptions. Throws type_error.310 if called on JSON values other than arrays; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than objects; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than strings; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap() with boolean\" Complexity \u00b6 Constant. Examples \u00b6 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: j 1 = { \"e\" : 2.718281828459045 , \"pi\" : 3.141592653589793 } j 2 = [ 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\" }} objec t = { \"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\" ] s tr i n g = t he bad Example: Swap string (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 } bi nar y = { \"bytes\" :[ 1 , 2 , 3 ], \"subtype\" : null } See also \u00b6 std::swap Version history \u00b6 Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 3.8.0. Since version 3.8.0.","title":"swap"},{"location":"api/basic_json/swap/#nlohmannbasic_jsonswap","text":"// (1) void swap ( reference other ) noexcept ; // (2) void swap ( reference left , reference right ) noexcept ; // (3) void swap ( array_t & other ); // (4) void swap ( object_t & other ); // (5) void swap ( string_t & other ); // (6) void swap ( binary_t & other ); // (7) void swap ( typename binary_t :: container_type & other ); Exchanges the contents of the JSON value with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. 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. Exchanges the contents of a JSON array with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a JSON object with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a JSON string with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a binary value with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Exchanges the contents of a binary value with those of other . Does not invoke any move, copy, or swap operations on individual elements. All iterators and references remain valid. The past-the-end iterator is invalidated. Unlike version (6), no binary subtype is involved.","title":"nlohmann::basic_json::swap"},{"location":"api/basic_json/swap/#parameters","text":"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","title":"Parameters"},{"location":"api/basic_json/swap/#exceptions","text":"No-throw guarantee: this function never throws exceptions. No-throw guarantee: this function never throws exceptions. Throws type_error.310 if called on JSON values other than arrays; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than objects; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than strings; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap() with boolean\" Throws type_error.310 if called on JSON values other than binaries; example: \"cannot use swap() with boolean\"","title":"Exceptions"},{"location":"api/basic_json/swap/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/swap/#examples","text":"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: j 1 = { \"e\" : 2.718281828459045 , \"pi\" : 3.141592653589793 } j 2 = [ 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\" }} objec t = { \"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\" ] s tr i n g = t he bad Example: Swap string (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 } bi nar y = { \"bytes\" :[ 1 , 2 , 3 ], \"subtype\" : null }","title":"Examples"},{"location":"api/basic_json/swap/#see-also","text":"std::swap","title":"See also"},{"location":"api/basic_json/swap/#version-history","text":"Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 1.0.0. Since version 3.8.0. Since version 3.8.0.","title":"Version history"},{"location":"api/basic_json/to_bjdata/","text":"nlohmann::basic_json:: to_bjdata \u00b6 // (1) static std :: vector < std :: uint8_t > to_bjdata ( const basic_json & j , const bool use_size = false , const bool use_type = false ); // (2) static void to_bjdata ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o , const bool use_size = false , const bool use_type = false ); static void to_bjdata ( const basic_json & j , detail :: output_adapter < char > o , const bool use_size = false , const bool use_type = false ); 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. Returns a byte vector containing the BJData serialization. Writes the BJData serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page . Parameters \u00b6 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 \u00b6 BJData serialization as byte vector (none) Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the size of the JSON value j . Examples \u00b6 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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_bjdata ( array ); // serialize it to BJData using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_bjdata ( array , true ); // serialize it to BJData using type optimization std :: vector < std :: uint8_t > 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: { i 7 compac t Ti 6 schemaF } [ i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 ] [ #i 8 i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 [ $i#i 812345678 Version history \u00b6 Added in version 3.11.0.","title":"to_bjdata"},{"location":"api/basic_json/to_bjdata/#nlohmannbasic_jsonto_bjdata","text":"// (1) static std :: vector < std :: uint8_t > to_bjdata ( const basic_json & j , const bool use_size = false , const bool use_type = false ); // (2) static void to_bjdata ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o , const bool use_size = false , const bool use_type = false ); static void to_bjdata ( const basic_json & j , detail :: output_adapter < char > o , const bool use_size = false , const bool use_type = false ); 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. Returns a byte vector containing the BJData serialization. Writes the BJData serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::to_bjdata"},{"location":"api/basic_json/to_bjdata/#parameters","text":"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.","title":"Parameters"},{"location":"api/basic_json/to_bjdata/#return-value","text":"BJData serialization as byte vector (none)","title":"Return value"},{"location":"api/basic_json/to_bjdata/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/to_bjdata/#complexity","text":"Linear in the size of the JSON value j .","title":"Complexity"},{"location":"api/basic_json/to_bjdata/#examples","text":"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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_bjdata ( array ); // serialize it to BJData using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_bjdata ( array , true ); // serialize it to BJData using type optimization std :: vector < std :: uint8_t > 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: { i 7 compac t Ti 6 schemaF } [ i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 ] [ #i 8 i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 [ $i#i 812345678","title":"Examples"},{"location":"api/basic_json/to_bjdata/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/basic_json/to_bson/","text":"nlohmann::basic_json:: to_bson \u00b6 // (1) static std :: vector < std :: uint8_t > to_bson ( const basic_json & j ); // (2) static void to_bson ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o ); static void to_bson ( const basic_json & j , detail :: output_adapter < char > 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). Returns a byte vector containing the BSON serialization. Writes the BSON serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page . Parameters \u00b6 j (in) JSON value to serialize o (in) output adapter to write serialization to Return value \u00b6 BSON serialization as byte vector (none) Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the size of the JSON value j . Examples \u00b6 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 < std :: uint8_t > 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: 0 x 1 b 0 x 00 0 x 00 0 x 00 0 x 08 0 x 63 0 x 6 f 0 x 6 d 0 x 70 0 x 61 0 x 63 0 x 74 0 x 00 0 x 01 0 x 10 0 x 73 0 x 63 0 x 68 0 x 65 0 x 6 d 0 x 61 0 x 00 0 x 00 0 x 00 0 x 00 0 x 00 0 x 00 Version history \u00b6 Added in version 3.4.0.","title":"to_bson"},{"location":"api/basic_json/to_bson/#nlohmannbasic_jsonto_bson","text":"// (1) static std :: vector < std :: uint8_t > to_bson ( const basic_json & j ); // (2) static void to_bson ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o ); static void to_bson ( const basic_json & j , detail :: output_adapter < char > 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). Returns a byte vector containing the BSON serialization. Writes the BSON serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::to_bson"},{"location":"api/basic_json/to_bson/#parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to","title":"Parameters"},{"location":"api/basic_json/to_bson/#return-value","text":"BSON serialization as byte vector (none)","title":"Return value"},{"location":"api/basic_json/to_bson/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/to_bson/#complexity","text":"Linear in the size of the JSON value j .","title":"Complexity"},{"location":"api/basic_json/to_bson/#examples","text":"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 < std :: uint8_t > 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: 0 x 1 b 0 x 00 0 x 00 0 x 00 0 x 08 0 x 63 0 x 6 f 0 x 6 d 0 x 70 0 x 61 0 x 63 0 x 74 0 x 00 0 x 01 0 x 10 0 x 73 0 x 63 0 x 68 0 x 65 0 x 6 d 0 x 61 0 x 00 0 x 00 0 x 00 0 x 00 0 x 00 0 x 00","title":"Examples"},{"location":"api/basic_json/to_bson/#version-history","text":"Added in version 3.4.0.","title":"Version history"},{"location":"api/basic_json/to_cbor/","text":"nlohmann::basic_json:: to_cbor \u00b6 // (1) static std :: vector < std :: uint8_t > to_cbor ( const basic_json & j ); // (2) static void to_cbor ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o ); static void to_cbor ( const basic_json & j , detail :: output_adapter < char > 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 which aims to be more compact than JSON itself, yet more efficient to parse. Returns a byte vector containing the CBOR serialization. Writes the CBOR serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page . Parameters \u00b6 j (in) JSON value to serialize o (in) output adapter to write serialization to Return value \u00b6 CBOR serialization as byte vector (none) Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the size of the JSON value j . Examples \u00b6 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 < std :: uint8_t > 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: 0 xa 2 0 x 67 0 x 63 0 x 6 f 0 x 6 d 0 x 70 0 x 61 0 x 63 0 x 74 0 x f 5 0 x 66 0 x 73 0 x 63 0 x 68 0 x 65 0 x 6 d 0 x 61 0 x 00 Version history \u00b6 Added in version 2.0.9. Compact representation of floating-point numbers added in version 3.8.0.","title":"to_cbor"},{"location":"api/basic_json/to_cbor/#nlohmannbasic_jsonto_cbor","text":"// (1) static std :: vector < std :: uint8_t > to_cbor ( const basic_json & j ); // (2) static void to_cbor ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o ); static void to_cbor ( const basic_json & j , detail :: output_adapter < char > 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 which aims to be more compact than JSON itself, yet more efficient to parse. Returns a byte vector containing the CBOR serialization. Writes the CBOR serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::to_cbor"},{"location":"api/basic_json/to_cbor/#parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to","title":"Parameters"},{"location":"api/basic_json/to_cbor/#return-value","text":"CBOR serialization as byte vector (none)","title":"Return value"},{"location":"api/basic_json/to_cbor/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/to_cbor/#complexity","text":"Linear in the size of the JSON value j .","title":"Complexity"},{"location":"api/basic_json/to_cbor/#examples","text":"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 < std :: uint8_t > 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: 0 xa 2 0 x 67 0 x 63 0 x 6 f 0 x 6 d 0 x 70 0 x 61 0 x 63 0 x 74 0 x f 5 0 x 66 0 x 73 0 x 63 0 x 68 0 x 65 0 x 6 d 0 x 61 0 x 00","title":"Examples"},{"location":"api/basic_json/to_cbor/#version-history","text":"Added in version 2.0.9. Compact representation of floating-point numbers added in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/to_msgpack/","text":"nlohmann::basic_json:: to_msgpack \u00b6 // (1) static std :: vector < std :: uint8_t > to_msgpack ( const basic_json & j ); // (2) static void to_msgpack ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o ); static void to_msgpack ( const basic_json & j , detail :: output_adapter < char > o ); Serializes a given JSON value j to a byte vector using the MessagePack serialization format. MessagePack is a binary serialization format which aims to be more compact than JSON itself, yet more efficient to parse. Returns a byte vector containing the MessagePack serialization. Writes the MessagePack serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page . Parameters \u00b6 j (in) JSON value to serialize o (in) output adapter to write serialization to Return value \u00b6 MessagePack serialization as byte vector (none) Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the size of the JSON value j . Examples \u00b6 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 < std :: uint8_t > 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: 0 x 82 0 xa 7 0 x 63 0 x 6 f 0 x 6 d 0 x 70 0 x 61 0 x 63 0 x 74 0 xc 3 0 xa 6 0 x 73 0 x 63 0 x 68 0 x 65 0 x 6 d 0 x 61 0 x 00 Version history \u00b6 Added in version 2.0.9.","title":"to_msgpack"},{"location":"api/basic_json/to_msgpack/#nlohmannbasic_jsonto_msgpack","text":"// (1) static std :: vector < std :: uint8_t > to_msgpack ( const basic_json & j ); // (2) static void to_msgpack ( const basic_json & j , detail :: output_adapter < std :: uint8_t > o ); static void to_msgpack ( const basic_json & j , detail :: output_adapter < char > o ); Serializes a given JSON value j to a byte vector using the MessagePack serialization format. MessagePack is a binary serialization format which aims to be more compact than JSON itself, yet more efficient to parse. Returns a byte vector containing the MessagePack serialization. Writes the MessagePack serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::to_msgpack"},{"location":"api/basic_json/to_msgpack/#parameters","text":"j (in) JSON value to serialize o (in) output adapter to write serialization to","title":"Parameters"},{"location":"api/basic_json/to_msgpack/#return-value","text":"MessagePack serialization as byte vector (none)","title":"Return value"},{"location":"api/basic_json/to_msgpack/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/to_msgpack/#complexity","text":"Linear in the size of the JSON value j .","title":"Complexity"},{"location":"api/basic_json/to_msgpack/#examples","text":"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 < std :: uint8_t > 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: 0 x 82 0 xa 7 0 x 63 0 x 6 f 0 x 6 d 0 x 70 0 x 61 0 x 63 0 x 74 0 xc 3 0 xa 6 0 x 73 0 x 63 0 x 68 0 x 65 0 x 6 d 0 x 61 0 x 00","title":"Examples"},{"location":"api/basic_json/to_msgpack/#version-history","text":"Added in version 2.0.9.","title":"Version history"},{"location":"api/basic_json/to_string/","text":"to_string(basic_json) \u00b6 template < typename BasicJsonType > std :: string to_string ( const BasicJsonType & j ); This function implements a user-defined to_string for JSON objects. Template parameters \u00b6 BasicJsonType a specialization of basic_json Return value \u00b6 string containing the serialization of the JSON value Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Exceptions \u00b6 Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded Complexity \u00b6 Linear. Possible implementation \u00b6 template < typename BasicJsonType > std :: string to_string ( const BasicJsonType & j ) { return j . dump (); } Examples \u00b6 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 \u00b6 dump Version history \u00b6 Added in version 3.7.0.","title":"to_string"},{"location":"api/basic_json/to_string/#to_stringbasic_json","text":"template < typename BasicJsonType > std :: string to_string ( const BasicJsonType & j ); This function implements a user-defined to_string for JSON objects.","title":"to_string(basic_json)"},{"location":"api/basic_json/to_string/#template-parameters","text":"BasicJsonType a specialization of basic_json","title":"Template parameters"},{"location":"api/basic_json/to_string/#return-value","text":"string containing the serialization of the JSON value","title":"Return value"},{"location":"api/basic_json/to_string/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes to any JSON value.","title":"Exception safety"},{"location":"api/basic_json/to_string/#exceptions","text":"Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded","title":"Exceptions"},{"location":"api/basic_json/to_string/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/to_string/#possible-implementation","text":"template < typename BasicJsonType > std :: string to_string ( const BasicJsonType & j ) { return j . dump (); }","title":"Possible implementation"},{"location":"api/basic_json/to_string/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/to_string/#see-also","text":"dump","title":"See also"},{"location":"api/basic_json/to_string/#version-history","text":"Added in version 3.7.0.","title":"Version history"},{"location":"api/basic_json/to_ubjson/","text":"nlohmann::basic_json:: to_ubjson \u00b6 // (1) static std :: vector < std :: uint8_t > 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 < std :: uint8_t > o , const bool use_size = false , const bool use_type = false ); static void to_ubjson ( const basic_json & j , detail :: output_adapter < char > 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. Returns a byte vector containing the UBJSON serialization. Writes the UBJSON serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page . Parameters \u00b6 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 \u00b6 UBJSON serialization as byte vector (none) Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes in the JSON value. Complexity \u00b6 Linear in the size of the JSON value j . Examples \u00b6 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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_ubjson ( array ); // serialize it to UBJSON using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_ubjson ( array , true ); // serialize it to UBJSON using type optimization std :: vector < std :: uint8_t > 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: { i 7 compac t Ti 6 schemaF } [ i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 ] [ #i 8 i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 [ $i#i 812345678 Version history \u00b6 Added in version 3.1.0.","title":"to_ubjson"},{"location":"api/basic_json/to_ubjson/#nlohmannbasic_jsonto_ubjson","text":"// (1) static std :: vector < std :: uint8_t > 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 < std :: uint8_t > o , const bool use_size = false , const bool use_type = false ); static void to_ubjson ( const basic_json & j , detail :: output_adapter < char > 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. Returns a byte vector containing the UBJSON serialization. Writes the UBJSON serialization to an output adapter. The exact mapping and its limitations is described on a dedicated page .","title":"nlohmann::basic_json::to_ubjson"},{"location":"api/basic_json/to_ubjson/#parameters","text":"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.","title":"Parameters"},{"location":"api/basic_json/to_ubjson/#return-value","text":"UBJSON serialization as byte vector (none)","title":"Return value"},{"location":"api/basic_json/to_ubjson/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes in the JSON value.","title":"Exception safety"},{"location":"api/basic_json/to_ubjson/#complexity","text":"Linear in the size of the JSON value j .","title":"Complexity"},{"location":"api/basic_json/to_ubjson/#examples","text":"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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_ubjson ( array ); // serialize it to UBJSON using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_ubjson ( array , true ); // serialize it to UBJSON using type optimization std :: vector < std :: uint8_t > 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: { i 7 compac t Ti 6 schemaF } [ i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 ] [ #i 8 i 1 i 2 i 3 i 4 i 5 i 6 i 7 i 8 [ $i#i 812345678","title":"Examples"},{"location":"api/basic_json/to_ubjson/#version-history","text":"Added in version 3.1.0.","title":"Version history"},{"location":"api/basic_json/type/","text":"nlohmann::basic_json:: type \u00b6 constexpr value_t type () const noexcept ; Return the type of the JSON value as a value from the value_t enumeration. Return value \u00b6 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 \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 1.0.0. Added unsigned integer type in version 2.0.0. Added binary type in version 3.8.0.","title":"type"},{"location":"api/basic_json/type/#nlohmannbasic_jsontype","text":"constexpr value_t type () const noexcept ; Return the type of the JSON value as a value from the value_t enumeration.","title":"nlohmann::basic_json::type"},{"location":"api/basic_json/type/#return-value","text":"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","title":"Return value"},{"location":"api/basic_json/type/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/type/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/type/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/type/#version-history","text":"Added in version 1.0.0. Added unsigned integer type in version 2.0.0. Added binary type in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/type_error/","text":"nlohmann::basic_json:: type_error \u00b6 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 ). Member functions \u00b6 what - returns explanatory string Member variables \u00b6 id - the id of the exception Examples \u00b6 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 ( json :: type_error & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n . t ype_error. 308 ] ca nn o t use push_back() wi t h s tr i n g excep t io n id : 308 See also \u00b6 List of type errors parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors Version history \u00b6 Since version 3.0.0.","title":"type_error"},{"location":"api/basic_json/type_error/#nlohmannbasic_jsontype_error","text":"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 ).","title":"nlohmann::basic_json::type_error"},{"location":"api/basic_json/type_error/#member-functions","text":"what - returns explanatory string","title":"Member functions"},{"location":"api/basic_json/type_error/#member-variables","text":"id - the id of the exception","title":"Member variables"},{"location":"api/basic_json/type_error/#examples","text":"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 ( json :: type_error & e ) { // output exception information std :: cout << \"message: \" << e . what () << '\\n' << \"exception id: \" << e . id << std :: endl ; } } Output: message : [ jso n .excep t io n . t ype_error. 308 ] ca nn o t use push_back() wi t h s tr i n g excep t io n id : 308","title":"Examples"},{"location":"api/basic_json/type_error/#see-also","text":"List of type errors parse_error for exceptions indicating a parse error invalid_iterator for exceptions indicating errors with iterators out_of_range for exceptions indicating access out of the defined range other_error for exceptions indicating other library errors","title":"See also"},{"location":"api/basic_json/type_error/#version-history","text":"Since version 3.0.0.","title":"Version history"},{"location":"api/basic_json/type_name/","text":"nlohmann::basic_json:: type_name \u00b6 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 \u00b6 a string representation of the type ( value_t ): 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 \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 boolea n -17 is a nu mber 42 is a nu mber 23.42 is a nu mber { \"one\" : 1 , \"two\" : 2 } is a n objec t [ 1 , 2 , 4 , 8 , 16 ] is a n array \"Hello, world\" is a s tr i n g Version history \u00b6 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.","title":"type_name"},{"location":"api/basic_json/type_name/#nlohmannbasic_jsontype_name","text":"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.","title":"nlohmann::basic_json::type_name"},{"location":"api/basic_json/type_name/#return-value","text":"a string representation of the type ( value_t ): 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\"","title":"Return value"},{"location":"api/basic_json/type_name/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/type_name/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/basic_json/type_name/#examples","text":"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 boolea n -17 is a nu mber 42 is a nu mber 23.42 is a nu mber { \"one\" : 1 , \"two\" : 2 } is a n objec t [ 1 , 2 , 4 , 8 , 16 ] is a n array \"Hello, world\" is a s tr i n g","title":"Examples"},{"location":"api/basic_json/type_name/#version-history","text":"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.","title":"Version history"},{"location":"api/basic_json/unflatten/","text":"nlohmann::basic_json:: unflatten \u00b6 basic_json unflatten () const ; The function restores the arbitrary nesting of a JSON value that has been flattened before using the flatten() function. The JSON value must meet certain constraints: The value must be an object. The keys must be JSON pointers (see RFC 6901 ) The mapped values must be primitive JSON types. Return value \u00b6 the original JSON from a flattened version Exception safety \u00b6 Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 The function can throw the following exceptions: Throws type_error.314 if value is not an object Throws type_error.315 if object values are not primitive Complexity \u00b6 Linear in the size the JSON value. Notes \u00b6 Empty objects and arrays are flattened by flatten() to null values and can not unflattened to their original type. Apart from this example, for a JSON value j , the following is always true: j == j . flatten (). unflatten () . Examples \u00b6 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 \u00b6 flatten the reverse function Version history \u00b6 Added in version 2.0.0.","title":"unflatten"},{"location":"api/basic_json/unflatten/#nlohmannbasic_jsonunflatten","text":"basic_json unflatten () const ; The function restores the arbitrary nesting of a JSON value that has been flattened before using the flatten() function. The JSON value must meet certain constraints: The value must be an object. The keys must be JSON pointers (see RFC 6901 ) The mapped values must be primitive JSON types.","title":"nlohmann::basic_json::unflatten"},{"location":"api/basic_json/unflatten/#return-value","text":"the original JSON from a flattened version","title":"Return value"},{"location":"api/basic_json/unflatten/#exception-safety","text":"Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/basic_json/unflatten/#exceptions","text":"The function can throw the following exceptions: Throws type_error.314 if value is not an object Throws type_error.315 if object values are not primitive","title":"Exceptions"},{"location":"api/basic_json/unflatten/#complexity","text":"Linear in the size the JSON value.","title":"Complexity"},{"location":"api/basic_json/unflatten/#notes","text":"Empty objects and arrays are flattened by flatten() to null values and can not unflattened to their original type. Apart from this example, for a JSON value j , the following is always true: j == j . flatten (). unflatten () .","title":"Notes"},{"location":"api/basic_json/unflatten/#examples","text":"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 }","title":"Examples"},{"location":"api/basic_json/unflatten/#see-also","text":"flatten the reverse function","title":"See also"},{"location":"api/basic_json/unflatten/#version-history","text":"Added in version 2.0.0.","title":"Version history"},{"location":"api/basic_json/update/","text":"nlohmann::basic_json:: update \u00b6 // (1) void update ( const_reference j , bool merge_objects = false ); // (2) void update ( const_iterator first , const_iterator last , bool merge_objects = false ); Inserts all values from JSON object j . 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. The function is motivated by Python's dict.update function. Parameters \u00b6 j (in) JSON object to read values from merge_objects (in) when true , existing keys are not overwritten, but contents of objects are merged recursively (default: false ) first (in) begin of the range of elements to insert last (in) end of the range of elements to insert Exceptions \u00b6 The function can throw the following exceptions: Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\" The function can throw the following exceptions: Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\" Throws invalid_iterator.202 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 if first and last do not belong to the same JSON value; example: \"iterators do not fit\" Complexity \u00b6 O(N*log(size() + N)), where N is the number of elements to insert. O(N*log(size() + N)), where N is the number of elements to insert. Examples \u00b6 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\u00f3n\" }, } 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\u00f3n\" } } 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\u00f3n\" } } Version history \u00b6 Added in version 3.0.0. Added merge_objects parameter in 3.10.4.","title":"update"},{"location":"api/basic_json/update/#nlohmannbasic_jsonupdate","text":"// (1) void update ( const_reference j , bool merge_objects = false ); // (2) void update ( const_iterator first , const_iterator last , bool merge_objects = false ); Inserts all values from JSON object j . 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. The function is motivated by Python's dict.update function.","title":"nlohmann::basic_json::update"},{"location":"api/basic_json/update/#parameters","text":"j (in) JSON object to read values from merge_objects (in) when true , existing keys are not overwritten, but contents of objects are merged recursively (default: false ) first (in) begin of the range of elements to insert last (in) end of the range of elements to insert","title":"Parameters"},{"location":"api/basic_json/update/#exceptions","text":"The function can throw the following exceptions: Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\" The function can throw the following exceptions: Throws type_error.312 if called on JSON values other than objects; example: \"cannot use update() with string\" Throws invalid_iterator.202 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 if first and last do not belong to the same JSON value; example: \"iterators do not fit\"","title":"Exceptions"},{"location":"api/basic_json/update/#complexity","text":"O(N*log(size() + N)), where N is the number of elements to insert. O(N*log(size() + N)), where N is the number of elements to insert.","title":"Complexity"},{"location":"api/basic_json/update/#examples","text":"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\u00f3n\" }, } 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\u00f3n\" } } 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\u00f3n\" } }","title":"Examples"},{"location":"api/basic_json/update/#version-history","text":"Added in version 3.0.0. Added merge_objects parameter in 3.10.4.","title":"Version history"},{"location":"api/basic_json/value/","text":"nlohmann::basic_json:: value \u00b6 // (1) template < class ValueType > ValueType value ( const typename object_t :: key_type & key , ValueType && default_value ) const ; // (2) template < class ValueType , class KeyType > ValueType value ( KeyType && key , ValueType && default_value ) const ; // (3) template < class ValueType > ValueType value ( const json_pointer & ptr , const ValueType & default_value ) const ; 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 ; } 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. 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 , this function does not throw if the given key / ptr was not found. Unlike operator[] , 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 \u00b6 KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . 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 \u00b6 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 \u00b6 copy of the element at key key or default_value if key is not found copy of the element at key key or default_value if key is not found copy of the element at JSON Pointer ptr or default_value if no value for ptr is found Exception safety \u00b6 Strong guarantee: if an exception is thrown, there are no changes to any JSON value. Exceptions \u00b6 The function can throw the following exceptions: Throws type_error.302 if default_value does not match the type of the value at key Throws type_error.306 if the JSON value is not an object; in that case, using value() with a key makes no sense. See 1. The function can throw the following exceptions: Throws type_error.302 if default_value does not match the type of the value at ptr Throws type_error.306 if the JSON value is not an object; in that case, using value() with a key makes no sense. Complexity \u00b6 Logarithmic in the size of the container. Logarithmic in the size of the container. Logarithmic in the size of the container. Examples \u00b6 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 \u00b6 see at for access by reference with range checking see operator[] for unchecked access by reference Version history \u00b6 Added in version 1.0.0. Changed parameter default_value type from const ValueType& to ValueType&& in version 3.11.0. Added in version 3.11.0. Made ValueType the first template parameter in version 3.11.2. Added in version 2.0.2.","title":"value"},{"location":"api/basic_json/value/#nlohmannbasic_jsonvalue","text":"// (1) template < class ValueType > ValueType value ( const typename object_t :: key_type & key , ValueType && default_value ) const ; // (2) template < class ValueType , class KeyType > ValueType value ( KeyType && key , ValueType && default_value ) const ; // (3) template < class ValueType > ValueType value ( const json_pointer & ptr , const ValueType & default_value ) const ; 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 ; } 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. 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 , this function does not throw if the given key / ptr was not found. Unlike operator[] , 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.","title":"nlohmann::basic_json::value"},{"location":"api/basic_json/value/#template-parameters","text":"KeyType A type for an object key other than json_pointer that is comparable with string_t using object_comparator_t . 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.","title":"Template parameters"},{"location":"api/basic_json/value/#parameters","text":"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","title":"Parameters"},{"location":"api/basic_json/value/#return-value","text":"copy of the element at key key or default_value if key is not found copy of the element at key key or default_value if key is not found copy of the element at JSON Pointer ptr or default_value if no value for ptr is found","title":"Return value"},{"location":"api/basic_json/value/#exception-safety","text":"Strong guarantee: if an exception is thrown, there are no changes to any JSON value.","title":"Exception safety"},{"location":"api/basic_json/value/#exceptions","text":"The function can throw the following exceptions: Throws type_error.302 if default_value does not match the type of the value at key Throws type_error.306 if the JSON value is not an object; in that case, using value() with a key makes no sense. See 1. The function can throw the following exceptions: Throws type_error.302 if default_value does not match the type of the value at ptr Throws type_error.306 if the JSON value is not an object; in that case, using value() with a key makes no sense.","title":"Exceptions"},{"location":"api/basic_json/value/#complexity","text":"Logarithmic in the size of the container. Logarithmic in the size of the container. Logarithmic in the size of the container.","title":"Complexity"},{"location":"api/basic_json/value/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/value/#see-also","text":"see at for access by reference with range checking see operator[] for unchecked access by reference","title":"See also"},{"location":"api/basic_json/value/#version-history","text":"Added in version 1.0.0. Changed parameter default_value type from const ValueType& to ValueType&& in version 3.11.0. Added in version 3.11.0. Made ValueType the first template parameter in version 3.11.2. Added in version 2.0.2.","title":"Version history"},{"location":"api/basic_json/value_t/","text":"nlohmann::basic_json:: value_t \u00b6 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_object , is_array , is_string , is_boolean , is_number (with is_number_integer , is_number_unsigned , and is_number_float ), is_discarded , is_binary , is_primitive , and is_structured rely on it. Notes \u00b6 Ordering The order of types is as follows: null boolean number_integer , number_unsigned , number_float object array string 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 for unsigned integers number_integer_t for signed integers number_float_t 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 \u00b6 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 \u00b6 Added in version 1.0.0. Added unsigned integer type in version 2.0.0. Added binary type in version 3.8.0.","title":"value_t"},{"location":"api/basic_json/value_t/#nlohmannbasic_jsonvalue_t","text":"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_object , is_array , is_string , is_boolean , is_number (with is_number_integer , is_number_unsigned , and is_number_float ), is_discarded , is_binary , is_primitive , and is_structured rely on it.","title":"nlohmann::basic_json::value_t"},{"location":"api/basic_json/value_t/#notes","text":"Ordering The order of types is as follows: null boolean number_integer , number_unsigned , number_float object array string 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 for unsigned integers number_integer_t for signed integers number_float_t 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","title":"Notes"},{"location":"api/basic_json/value_t/#examples","text":"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","title":"Examples"},{"location":"api/basic_json/value_t/#version-history","text":"Added in version 1.0.0. Added unsigned integer type in version 2.0.0. Added binary type in version 3.8.0.","title":"Version history"},{"location":"api/basic_json/~basic_json/","text":"nlohmann::basic_json:: ~basic_json \u00b6 ~ basic_json () noexcept ; Destroys the JSON value and frees all allocated memory. Exception safety \u00b6 No-throw guarantee: this member function never throws exceptions. Complexity \u00b6 Linear. Version history \u00b6 Added in version 1.0.0.","title":"(Destructor)"},{"location":"api/basic_json/~basic_json/#nlohmannbasic_jsonbasic_json","text":"~ basic_json () noexcept ; Destroys the JSON value and frees all allocated memory.","title":"nlohmann::basic_json::~basic_json"},{"location":"api/basic_json/~basic_json/#exception-safety","text":"No-throw guarantee: this member function never throws exceptions.","title":"Exception safety"},{"location":"api/basic_json/~basic_json/#complexity","text":"Linear.","title":"Complexity"},{"location":"api/basic_json/~basic_json/#version-history","text":"Added in version 1.0.0.","title":"Version history"},{"location":"api/byte_container_with_subtype/","text":"nlohmann:: byte_container_with_subtype \u00b6 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 \u00b6 BinaryType container to store bytes ( std :: vector < std :: uint8_t > by default) Member types \u00b6 container_type - the type of the underlying container ( BinaryType ) subtype_type - the type of the subtype ( std :: uint64_t ) Member functions \u00b6 (constructor) operator== - comparison: equal operator!= - comparison: not equal set_subtype - sets the binary subtype subtype - return the binary subtype has_subtype - return whether the value has a subtype clear_subtype - clears the binary subtype Version history \u00b6 Added in version 3.8.0. Changed type of subtypes to std :: uint64_t in 3.10.0.","title":"Overview"},{"location":"api/byte_container_with_subtype/#nlohmannbyte_container_with_subtype","text":"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.","title":"nlohmann::byte_container_with_subtype"},{"location":"api/byte_container_with_subtype/#template-parameters","text":"BinaryType container to store bytes ( std :: vector < std :: uint8_t > by default)","title":"Template parameters"},{"location":"api/byte_container_with_subtype/#member-types","text":"container_type - the type of the underlying container ( BinaryType ) subtype_type - the type of the subtype ( std :: uint64_t )","title":"Member types"},{"location":"api/byte_container_with_subtype/#member-functions","text":"(constructor) operator== - comparison: equal operator!= - comparison: not equal set_subtype - sets the binary subtype subtype - return the binary subtype has_subtype - return whether the value has a subtype clear_subtype - clears the binary subtype","title":"Member functions"},{"location":"api/byte_container_with_subtype/#version-history","text":"Added in version 3.8.0. Changed type of subtypes to std :: uint64_t in 3.10.0.","title":"Version history"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/","text":"nlohmann::byte_container_with_subtype:: byte_container_with_subtype \u00b6 // (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 ); Create empty binary container without subtype. Create binary container without subtype. Create binary container with subtype. Parameters \u00b6 container (in) binary container subtype (in) subtype Examples \u00b6 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 < std :: vector < std :: uint8_t >> ; using json = nlohmann :: json ; int main () { // (1) create empty container auto c1 = byte_container_with_subtype (); std :: vector < std :: uint8_t > 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 \u00b6 Since version 3.8.0.","title":"(constructor)"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#nlohmannbyte_container_with_subtypebyte_container_with_subtype","text":"// (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 ); Create empty binary container without subtype. Create binary container without subtype. Create binary container with subtype.","title":"nlohmann::byte_container_with_subtype::byte_container_with_subtype"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#parameters","text":"container (in) binary container subtype (in) subtype","title":"Parameters"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#examples","text":"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 < std :: vector < std :: uint8_t >> ; using json = nlohmann :: json ; int main () { // (1) create empty container auto c1 = byte_container_with_subtype (); std :: vector < std :: uint8_t > 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 }","title":"Examples"},{"location":"api/byte_container_with_subtype/byte_container_with_subtype/#version-history","text":"Since version 3.8.0.","title":"Version history"},{"location":"api/byte_container_with_subtype/clear_subtype/","text":"nlohmann::byte_container_with_subtype:: clear_subtype \u00b6 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 \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 < std :: vector < std :: uint8_t >> ; using json = nlohmann :: json ; int main () { std :: vector < std :: uint8_t > 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: be f ore calli n g clear_sub t ype() : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : 42 } a fter calli n g clear_sub t ype() : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : null } Version history \u00b6 Since version 3.8.0.","title":"clear_subtype"},{"location":"api/byte_container_with_subtype/clear_subtype/#nlohmannbyte_container_with_subtypeclear_subtype","text":"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.","title":"nlohmann::byte_container_with_subtype::clear_subtype"},{"location":"api/byte_container_with_subtype/clear_subtype/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/byte_container_with_subtype/clear_subtype/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/byte_container_with_subtype/clear_subtype/#examples","text":"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 < std :: vector < std :: uint8_t >> ; using json = nlohmann :: json ; int main () { std :: vector < std :: uint8_t > 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: be f ore calli n g clear_sub t ype() : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : 42 } a fter calli n g clear_sub t ype() : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : null }","title":"Examples"},{"location":"api/byte_container_with_subtype/clear_subtype/#version-history","text":"Since version 3.8.0.","title":"Version history"},{"location":"api/byte_container_with_subtype/has_subtype/","text":"nlohmann::byte_container_with_subtype:: has_subtype \u00b6 constexpr bool has_subtype () const noexcept ; Returns whether the value has a subtype. Return value \u00b6 whether the value has a subtype Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 < std :: vector < std :: uint8_t >> ; int main () { std :: vector < std :: uint8_t > 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 () << \" \\n c2.has_subtype() = \" << c2 . has_subtype () << std :: endl ; } Output: c 1. has_sub t ype() = false c 2. has_sub t ype() = true Version history \u00b6 Since version 3.8.0.","title":"has_subtype"},{"location":"api/byte_container_with_subtype/has_subtype/#nlohmannbyte_container_with_subtypehas_subtype","text":"constexpr bool has_subtype () const noexcept ; Returns whether the value has a subtype.","title":"nlohmann::byte_container_with_subtype::has_subtype"},{"location":"api/byte_container_with_subtype/has_subtype/#return-value","text":"whether the value has a subtype","title":"Return value"},{"location":"api/byte_container_with_subtype/has_subtype/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/byte_container_with_subtype/has_subtype/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/byte_container_with_subtype/has_subtype/#examples","text":"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 < std :: vector < std :: uint8_t >> ; int main () { std :: vector < std :: uint8_t > 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 () << \" \\n c2.has_subtype() = \" << c2 . has_subtype () << std :: endl ; } Output: c 1. has_sub t ype() = false c 2. has_sub t ype() = true","title":"Examples"},{"location":"api/byte_container_with_subtype/has_subtype/#version-history","text":"Since version 3.8.0.","title":"Version history"},{"location":"api/byte_container_with_subtype/set_subtype/","text":"nlohmann::byte_container_with_subtype:: set_subtype \u00b6 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 \u00b6 subtype (in) subtype to set Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 < std :: vector < std :: uint8_t >> ; using json = nlohmann :: json ; int main () { std :: vector < std :: uint8_t > 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: be f ore calli n g se t _sub t ype( 42 ) : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : null } a fter calli n g se t _sub t ype( 42 ) : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : 42 } Version history \u00b6 Since version 3.8.0.","title":"set_subtype"},{"location":"api/byte_container_with_subtype/set_subtype/#nlohmannbyte_container_with_subtypeset_subtype","text":"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.","title":"nlohmann::byte_container_with_subtype::set_subtype"},{"location":"api/byte_container_with_subtype/set_subtype/#parameters","text":"subtype (in) subtype to set","title":"Parameters"},{"location":"api/byte_container_with_subtype/set_subtype/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/byte_container_with_subtype/set_subtype/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/byte_container_with_subtype/set_subtype/#examples","text":"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 < std :: vector < std :: uint8_t >> ; using json = nlohmann :: json ; int main () { std :: vector < std :: uint8_t > 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: be f ore calli n g se t _sub t ype( 42 ) : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : null } a fter calli n g se t _sub t ype( 42 ) : { \"bytes\" :[ 202 , 254 , 186 , 190 ], \"subtype\" : 42 }","title":"Examples"},{"location":"api/byte_container_with_subtype/set_subtype/#version-history","text":"Since version 3.8.0.","title":"Version history"},{"location":"api/byte_container_with_subtype/subtype/","text":"nlohmann::byte_container_with_subtype:: subtype \u00b6 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 \u00b6 the numerical subtype of the binary value, or subtype_type(-1) if no subtype is set Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 < std :: vector < std :: uint8_t >> ; int main () { std :: vector < std :: uint8_t > 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 () << \" \\n c2.subtype() = \" << c2 . subtype () << std :: endl ; // in case no subtype is set, return special value assert ( c1 . subtype () == static_cast < byte_container_with_subtype :: subtype_type > ( -1 )); } Output: c 1. sub t ype() = 18446744073709551615 c 2. sub t ype() = 42 Version history \u00b6 Added in version 3.8.0 Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.","title":"subtype"},{"location":"api/byte_container_with_subtype/subtype/#nlohmannbyte_container_with_subtypesubtype","text":"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.","title":"nlohmann::byte_container_with_subtype::subtype"},{"location":"api/byte_container_with_subtype/subtype/#return-value","text":"the numerical subtype of the binary value, or subtype_type(-1) if no subtype is set","title":"Return value"},{"location":"api/byte_container_with_subtype/subtype/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/byte_container_with_subtype/subtype/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/byte_container_with_subtype/subtype/#examples","text":"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 < std :: vector < std :: uint8_t >> ; int main () { std :: vector < std :: uint8_t > 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 () << \" \\n c2.subtype() = \" << c2 . subtype () << std :: endl ; // in case no subtype is set, return special value assert ( c1 . subtype () == static_cast < byte_container_with_subtype :: subtype_type > ( -1 )); } Output: c 1. sub t ype() = 18446744073709551615 c 2. sub t ype() = 42","title":"Examples"},{"location":"api/byte_container_with_subtype/subtype/#version-history","text":"Added in version 3.8.0 Fixed return value to properly return subtype_type(-1) as documented in version 3.10.0.","title":"Version history"},{"location":"api/json_pointer/","text":"nlohmann:: json_pointer \u00b6 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 \u00b6 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 \u00b6 string_t - the string type used for the reference tokens Member functions \u00b6 (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 last reference token back - return last reference token push_back - append an unescaped token at the end of the pointer empty - return whether pointer points to the root document Literals \u00b6 operator\"\"_json_pointer - user-defined string literal for JSON pointers See also \u00b6 RFC 6901 Version history \u00b6 Added in version 2.0.0. Changed template parameter from basic_json to string type in version 3.11.0.","title":"Overview"},{"location":"api/json_pointer/#nlohmannjson_pointer","text":"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.","title":"nlohmann::json_pointer"},{"location":"api/json_pointer/#template-parameters","text":"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.","title":"Template parameters"},{"location":"api/json_pointer/#member-types","text":"string_t - the string type used for the reference tokens","title":"Member types"},{"location":"api/json_pointer/#member-functions","text":"(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 last reference token back - return last reference token push_back - append an unescaped token at the end of the pointer empty - return whether pointer points to the root document","title":"Member functions"},{"location":"api/json_pointer/#literals","text":"operator\"\"_json_pointer - user-defined string literal for JSON pointers","title":"Literals"},{"location":"api/json_pointer/#see-also","text":"RFC 6901","title":"See also"},{"location":"api/json_pointer/#version-history","text":"Added in version 2.0.0. Changed template parameter from basic_json to string type in version 3.11.0.","title":"Version history"},{"location":"api/json_pointer/back/","text":"nlohmann::json_pointer:: back \u00b6 const string_t & back () const ; Return last reference token. Return value \u00b6 Last reference token. Exceptions \u00b6 Throws out_of_range.405 if JSON pointer has no parent. Complexity \u00b6 Constant. Examples \u00b6 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: las t re feren ce t oke n o f \"/foo\" is \"foo\" las t re feren ce t oke n o f \"/foo/0\" is \"0\" Version history \u00b6 Added in version 3.6.0. Changed return type to string_t in version 3.11.0.","title":"back"},{"location":"api/json_pointer/back/#nlohmannjson_pointerback","text":"const string_t & back () const ; Return last reference token.","title":"nlohmann::json_pointer::back"},{"location":"api/json_pointer/back/#return-value","text":"Last reference token.","title":"Return value"},{"location":"api/json_pointer/back/#exceptions","text":"Throws out_of_range.405 if JSON pointer has no parent.","title":"Exceptions"},{"location":"api/json_pointer/back/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/json_pointer/back/#examples","text":"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: las t re feren ce t oke n o f \"/foo\" is \"foo\" las t re feren ce t oke n o f \"/foo/0\" is \"0\"","title":"Examples"},{"location":"api/json_pointer/back/#version-history","text":"Added in version 3.6.0. Changed return type to string_t in version 3.11.0.","title":"Version history"},{"location":"api/json_pointer/empty/","text":"nlohmann::json_pointer:: empty \u00b6 bool empty () const noexcept ; Return whether pointer points to the root document. Return value \u00b6 true iff the JSON pointer points to the root document. Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 3.6.0.","title":"empty"},{"location":"api/json_pointer/empty/#nlohmannjson_pointerempty","text":"bool empty () const noexcept ; Return whether pointer points to the root document.","title":"nlohmann::json_pointer::empty"},{"location":"api/json_pointer/empty/#return-value","text":"true iff the JSON pointer points to the root document.","title":"Return value"},{"location":"api/json_pointer/empty/#exception-safety","text":"No-throw guarantee: this function never throws exceptions.","title":"Exception safety"},{"location":"api/json_pointer/empty/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/json_pointer/empty/#examples","text":"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","title":"Examples"},{"location":"api/json_pointer/empty/#version-history","text":"Added in version 3.6.0.","title":"Version history"},{"location":"api/json_pointer/json_pointer/","text":"nlohmann::json_pointer:: json_pointer \u00b6 explicit json_pointer ( const string_t & s = \"\" ); Create a JSON pointer according to the syntax described in Section 3 of RFC6901 . Parameters \u00b6 s (in) string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value Exceptions \u00b6 Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash ( / ); see example below. Throws parse_error.108 if a tilde ( ~ ) in the given JSON pointer s is not followed by 0 (representing ~ ) or 1 (representing / ); see example below. Examples \u00b6 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 ( 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 ( 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 ( json :: parse_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: [ jso n .excep t io n .parse_error. 107 ] parse error a t by te 1 : JSON poi nter mus t be emp t y or begi n wi t h '/' - was : ' f oo' [ jso n .excep t io n .parse_error. 108 ] parse error : escape charac ter '~' mus t be f ollowed wi t h ' 0 ' or ' 1 ' [ jso n .excep t io n .parse_error. 108 ] parse error : escape charac ter '~' mus t be f ollowed wi t h ' 0 ' or ' 1 ' Version history \u00b6 Added in version 2.0.0. Changed type of s to string_t in version 3.11.0.","title":"(Constructor)"},{"location":"api/json_pointer/json_pointer/#nlohmannjson_pointerjson_pointer","text":"explicit json_pointer ( const string_t & s = \"\" ); Create a JSON pointer according to the syntax described in Section 3 of RFC6901 .","title":"nlohmann::json_pointer::json_pointer"},{"location":"api/json_pointer/json_pointer/#parameters","text":"s (in) string representing the JSON pointer; if omitted, the empty string is assumed which references the whole JSON value","title":"Parameters"},{"location":"api/json_pointer/json_pointer/#exceptions","text":"Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash ( / ); see example below. Throws parse_error.108 if a tilde ( ~ ) in the given JSON pointer s is not followed by 0 (representing ~ ) or 1 (representing / ); see example below.","title":"Exceptions"},{"location":"api/json_pointer/json_pointer/#examples","text":"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 ( 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 ( 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 ( json :: parse_error & e ) { std :: cout << e . what () << '\\n' ; } } Output: [ jso n .excep t io n .parse_error. 107 ] parse error a t by te 1 : JSON poi nter mus t be emp t y or begi n wi t h '/' - was : ' f oo' [ jso n .excep t io n .parse_error. 108 ] parse error : escape charac ter '~' mus t be f ollowed wi t h ' 0 ' or ' 1 ' [ jso n .excep t io n .parse_error. 108 ] parse error : escape charac ter '~' mus t be f ollowed wi t h ' 0 ' or ' 1 '","title":"Examples"},{"location":"api/json_pointer/json_pointer/#version-history","text":"Added in version 2.0.0. Changed type of s to string_t in version 3.11.0.","title":"Version history"},{"location":"api/json_pointer/operator_eq/","text":"nlohmann::json_pointer:: operator== \u00b6 // until C++20 template < typename RefStringTypeLhs , typename RefStringTypeRhs > bool operator == ( const json_pointer < RefStringTypeLhs >& lhs , const json_pointer < RefStringTypeRhs >& rhs ) noexcept ; // (1) template < typename RefStringTypeLhs , typename StringType > bool operator == ( const json_pointer < RefStringTypeLhs >& lhs , const StringType & rhs ); // (2) template < typename RefStringTypeRhs , typename StringType > bool operator == ( const StringType & lhs , const json_pointer < RefStringTypeRhs >& rhs ); // (2) // since C++20 class json_pointer { template < typename RefStringTypeRhs > bool operator == ( const json_pointer < RefStringTypeRhs >& rhs ) const noexcept ; // (1) bool operator == ( const string_t & rhs ) const ; // (2) }; Compares two JSON pointers for equality by comparing their reference tokens. 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 \u00b6 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 ) Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether the values lhs / *this and rhs are equal Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 (none) The function can throw the following exceptions: Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash ( / ); see example below. Throws parse_error.108 if a tilde ( ~ ) in the given JSON pointer s is not followed by 0 (representing ~ ) or 1 (representing / ); see example below. Complexity \u00b6 Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens. Notes \u00b6 Deprecation Overload 2 is deprecated and will be removed in a future major version release. Examples \u00b6 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 \u00b6 Added in version 2.1.0. Added C++20 member functions in version 3.11.2. Added for backward compatibility and deprecated in version 3.11.2.","title":"operator=="},{"location":"api/json_pointer/operator_eq/#nlohmannjson_pointeroperator","text":"// until C++20 template < typename RefStringTypeLhs , typename RefStringTypeRhs > bool operator == ( const json_pointer < RefStringTypeLhs >& lhs , const json_pointer < RefStringTypeRhs >& rhs ) noexcept ; // (1) template < typename RefStringTypeLhs , typename StringType > bool operator == ( const json_pointer < RefStringTypeLhs >& lhs , const StringType & rhs ); // (2) template < typename RefStringTypeRhs , typename StringType > bool operator == ( const StringType & lhs , const json_pointer < RefStringTypeRhs >& rhs ); // (2) // since C++20 class json_pointer { template < typename RefStringTypeRhs > bool operator == ( const json_pointer < RefStringTypeRhs >& rhs ) const noexcept ; // (1) bool operator == ( const string_t & rhs ) const ; // (2) }; Compares two JSON pointers for equality by comparing their reference tokens. 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.","title":"nlohmann::json_pointer::operator=="},{"location":"api/json_pointer/operator_eq/#template-parameters","text":"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 )","title":"Template parameters"},{"location":"api/json_pointer/operator_eq/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/json_pointer/operator_eq/#return-value","text":"whether the values lhs / *this and rhs are equal","title":"Return value"},{"location":"api/json_pointer/operator_eq/#exception-safety","text":"No-throw guarantee: this function never throws exceptions. Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/json_pointer/operator_eq/#exceptions","text":"(none) The function can throw the following exceptions: Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash ( / ); see example below. Throws parse_error.108 if a tilde ( ~ ) in the given JSON pointer s is not followed by 0 (representing ~ ) or 1 (representing / ); see example below.","title":"Exceptions"},{"location":"api/json_pointer/operator_eq/#complexity","text":"Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens.","title":"Complexity"},{"location":"api/json_pointer/operator_eq/#notes","text":"Deprecation Overload 2 is deprecated and will be removed in a future major version release.","title":"Notes"},{"location":"api/json_pointer/operator_eq/#examples","text":"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'","title":"Examples"},{"location":"api/json_pointer/operator_eq/#version-history","text":"Added in version 2.1.0. Added C++20 member functions in version 3.11.2. Added for backward compatibility and deprecated in version 3.11.2.","title":"Version history"},{"location":"api/json_pointer/operator_ne/","text":"nlohmann::json_pointer:: operator!= \u00b6 // until C++20 template < typename RefStringTypeLhs , typename RefStringTypeRhs > bool operator != ( const json_pointer < RefStringTypeLhs >& lhs , const json_pointer < RefStringTypeRhs >& rhs ) noexcept ; // (1) template < typename RefStringTypeLhs , typename StringType > bool operator != ( const json_pointer < RefStringTypeLhs >& lhs , const StringType & rhs ); // (2) template < typename RefStringTypeRhs , typename StringType > bool operator != ( const StringType & lhs , const json_pointer < RefStringTypeRhs >& rhs ); // (2) Compares two JSON pointers for inequality by comparing their reference tokens. 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 \u00b6 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 ) Parameters \u00b6 lhs (in) first value to consider rhs (in) second value to consider Return value \u00b6 whether the values lhs / *this and rhs are not equal Exception safety \u00b6 No-throw guarantee: this function never throws exceptions. Strong exception safety: if an exception occurs, the original value stays intact. Exceptions \u00b6 (none) The function can throw the following exceptions: Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash ( / ); see example below. Throws parse_error.108 if a tilde ( ~ ) in the given JSON pointer s is not followed by 0 (representing ~ ) or 1 (representing / ); see example below. Complexity \u00b6 Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens. Notes \u00b6 Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator== . Deprecation Overload 2 is deprecated and will be removed in a future major version release. Examples \u00b6 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 \u00b6 Added in version 2.1.0. Added for backward compatibility and deprecated in version 3.11.2.","title":"operator!="},{"location":"api/json_pointer/operator_ne/#nlohmannjson_pointeroperator","text":"// until C++20 template < typename RefStringTypeLhs , typename RefStringTypeRhs > bool operator != ( const json_pointer < RefStringTypeLhs >& lhs , const json_pointer < RefStringTypeRhs >& rhs ) noexcept ; // (1) template < typename RefStringTypeLhs , typename StringType > bool operator != ( const json_pointer < RefStringTypeLhs >& lhs , const StringType & rhs ); // (2) template < typename RefStringTypeRhs , typename StringType > bool operator != ( const StringType & lhs , const json_pointer < RefStringTypeRhs >& rhs ); // (2) Compares two JSON pointers for inequality by comparing their reference tokens. 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.","title":"nlohmann::json_pointer::operator!="},{"location":"api/json_pointer/operator_ne/#template-parameters","text":"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 )","title":"Template parameters"},{"location":"api/json_pointer/operator_ne/#parameters","text":"lhs (in) first value to consider rhs (in) second value to consider","title":"Parameters"},{"location":"api/json_pointer/operator_ne/#return-value","text":"whether the values lhs / *this and rhs are not equal","title":"Return value"},{"location":"api/json_pointer/operator_ne/#exception-safety","text":"No-throw guarantee: this function never throws exceptions. Strong exception safety: if an exception occurs, the original value stays intact.","title":"Exception safety"},{"location":"api/json_pointer/operator_ne/#exceptions","text":"(none) The function can throw the following exceptions: Throws parse_error.107 if the given JSON pointer s is nonempty and does not begin with a slash ( / ); see example below. Throws parse_error.108 if a tilde ( ~ ) in the given JSON pointer s is not followed by 0 (representing ~ ) or 1 (representing / ); see example below.","title":"Exceptions"},{"location":"api/json_pointer/operator_ne/#complexity","text":"Constant if lhs and rhs differ in the number of reference tokens, otherwise linear in the number of reference tokens.","title":"Complexity"},{"location":"api/json_pointer/operator_ne/#notes","text":"Operator overload resolution Since C++20 overload resolution will consider the rewritten candidate generated from operator== . Deprecation Overload 2 is deprecated and will be removed in a future major version release.","title":"Notes"},{"location":"api/json_pointer/operator_ne/#examples","text":"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'","title":"Examples"},{"location":"api/json_pointer/operator_ne/#version-history","text":"Added in version 2.1.0. Added for backward compatibility and deprecated in version 3.11.2.","title":"Version history"},{"location":"api/json_pointer/operator_slash/","text":"nlohmann::json_pointer:: operator/ \u00b6 // (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 ); create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer create a new JSON pointer by appending the unescaped token at the end of the JSON pointer create a new JSON pointer by appending the array-index-token at the end of the JSON pointer Parameters \u00b6 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 \u00b6 a new JSON pointer with rhs appended to lhs a new JSON pointer with unescaped token appended to lhs a new JSON pointer with array_idx appended to lhs Complexity \u00b6 Linear in the length of lhs and rhs . Linear in the length of lhs . Linear in the length of lhs . Examples \u00b6 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 \u00b6 Added in version 3.6.0. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0. Added in version 3.6.0.","title":"operator/"},{"location":"api/json_pointer/operator_slash/#nlohmannjson_pointeroperator","text":"// (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 ); create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer create a new JSON pointer by appending the unescaped token at the end of the JSON pointer create a new JSON pointer by appending the array-index-token at the end of the JSON pointer","title":"nlohmann::json_pointer::operator/"},{"location":"api/json_pointer/operator_slash/#parameters","text":"lhs (in) JSON pointer rhs (in) JSON pointer to append token (in) reference token to append array_idx (in) array index to append","title":"Parameters"},{"location":"api/json_pointer/operator_slash/#return-value","text":"a new JSON pointer with rhs appended to lhs a new JSON pointer with unescaped token appended to lhs a new JSON pointer with array_idx appended to lhs","title":"Return value"},{"location":"api/json_pointer/operator_slash/#complexity","text":"Linear in the length of lhs and rhs . Linear in the length of lhs . Linear in the length of lhs .","title":"Complexity"},{"location":"api/json_pointer/operator_slash/#examples","text":"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\"","title":"Examples"},{"location":"api/json_pointer/operator_slash/#version-history","text":"Added in version 3.6.0. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0. Added in version 3.6.0.","title":"Version history"},{"location":"api/json_pointer/operator_slasheq/","text":"nlohmann::json_pointer:: operator/= \u00b6 // (1) json_pointer & operator /= ( const json_pointer & ptr ); // (2) json_pointer & operator /= ( string_t token ); // (3) json_pointer & operator /= ( std :: size_t array_idx ) append another JSON pointer at the end of this JSON pointer append an unescaped reference token at the end of this JSON pointer append an array index at the end of this JSON pointer Parameters \u00b6 ptr (in) JSON pointer to append token (in) reference token to append array_idx (in) array index to append Return value \u00b6 JSON pointer with ptr appended JSON pointer with token appended without escaping token JSON pointer with array_idx appended Complexity \u00b6 Linear in the length of ptr . Amortized constant. Amortized constant. Examples \u00b6 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 \u00b6 Added in version 3.6.0. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0. Added in version 3.6.0.","title":"operator/="},{"location":"api/json_pointer/operator_slasheq/#nlohmannjson_pointeroperator","text":"// (1) json_pointer & operator /= ( const json_pointer & ptr ); // (2) json_pointer & operator /= ( string_t token ); // (3) json_pointer & operator /= ( std :: size_t array_idx ) append another JSON pointer at the end of this JSON pointer append an unescaped reference token at the end of this JSON pointer append an array index at the end of this JSON pointer","title":"nlohmann::json_pointer::operator/="},{"location":"api/json_pointer/operator_slasheq/#parameters","text":"ptr (in) JSON pointer to append token (in) reference token to append array_idx (in) array index to append","title":"Parameters"},{"location":"api/json_pointer/operator_slasheq/#return-value","text":"JSON pointer with ptr appended JSON pointer with token appended without escaping token JSON pointer with array_idx appended","title":"Return value"},{"location":"api/json_pointer/operator_slasheq/#complexity","text":"Linear in the length of ptr . Amortized constant. Amortized constant.","title":"Complexity"},{"location":"api/json_pointer/operator_slasheq/#examples","text":"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\"","title":"Examples"},{"location":"api/json_pointer/operator_slasheq/#version-history","text":"Added in version 3.6.0. Added in version 3.6.0. Changed type of token to string_t in version 3.11.0. Added in version 3.6.0.","title":"Version history"},{"location":"api/json_pointer/operator_string_t/","text":"nlohmann::json_pointer:: operator string_t \u00b6 operator string_t () const Return a string representation of the JSON pointer. Return value \u00b6 A string representation of the JSON pointer Possible implementation \u00b6 operator string_t () const { return to_string (); } Notes \u00b6 Deprecation This function is deprecated in favor of to_string and will be removed in a future major version release. Examples \u00b6 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: / f oo/ 0 /a~ 1 b Version history \u00b6 Since version 2.0.0. Changed type to string_t and deprecated in version 3.11.0.","title":"operator string_t"},{"location":"api/json_pointer/operator_string_t/#nlohmannjson_pointeroperator-string_t","text":"operator string_t () const Return a string representation of the JSON pointer.","title":"nlohmann::json_pointer::operator string_t"},{"location":"api/json_pointer/operator_string_t/#return-value","text":"A string representation of the JSON pointer","title":"Return value"},{"location":"api/json_pointer/operator_string_t/#possible-implementation","text":"operator string_t () const { return to_string (); }","title":"Possible implementation"},{"location":"api/json_pointer/operator_string_t/#notes","text":"Deprecation This function is deprecated in favor of to_string and will be removed in a future major version release.","title":"Notes"},{"location":"api/json_pointer/operator_string_t/#examples","text":"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: / f oo/ 0 /a~ 1 b","title":"Examples"},{"location":"api/json_pointer/operator_string_t/#version-history","text":"Since version 2.0.0. Changed type to string_t and deprecated in version 3.11.0.","title":"Version history"},{"location":"api/json_pointer/parent_pointer/","text":"nlohmann::json_pointer:: parent_pointer \u00b6 json_pointer parent_pointer () const ; Returns the parent of this JSON pointer. Return value \u00b6 Parent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned. Complexity \u00b6 Linear in the length of the JSON pointer. Examples \u00b6 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: pare nt o f \"\" is \"\" pare nt o f \"/foo\" is \"\" pare nt o f \"/foo/0\" is \"/foo\" Version history \u00b6 Added in version 3.6.0.","title":"parent_pointer"},{"location":"api/json_pointer/parent_pointer/#nlohmannjson_pointerparent_pointer","text":"json_pointer parent_pointer () const ; Returns the parent of this JSON pointer.","title":"nlohmann::json_pointer::parent_pointer"},{"location":"api/json_pointer/parent_pointer/#return-value","text":"Parent of this JSON pointer; in case this JSON pointer is the root, the root itself is returned.","title":"Return value"},{"location":"api/json_pointer/parent_pointer/#complexity","text":"Linear in the length of the JSON pointer.","title":"Complexity"},{"location":"api/json_pointer/parent_pointer/#examples","text":"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: pare nt o f \"\" is \"\" pare nt o f \"/foo\" is \"\" pare nt o f \"/foo/0\" is \"/foo\"","title":"Examples"},{"location":"api/json_pointer/parent_pointer/#version-history","text":"Added in version 3.6.0.","title":"Version history"},{"location":"api/json_pointer/pop_back/","text":"nlohmann::json_pointer:: pop_back \u00b6 void pop_back (); Remove last reference token. Exceptions \u00b6 Throws out_of_range.405 if JSON pointer has no parent. Complexity \u00b6 Constant. Examples \u00b6 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 \u00b6 Added in version 3.6.0.","title":"pop_back"},{"location":"api/json_pointer/pop_back/#nlohmannjson_pointerpop_back","text":"void pop_back (); Remove last reference token.","title":"nlohmann::json_pointer::pop_back"},{"location":"api/json_pointer/pop_back/#exceptions","text":"Throws out_of_range.405 if JSON pointer has no parent.","title":"Exceptions"},{"location":"api/json_pointer/pop_back/#complexity","text":"Constant.","title":"Complexity"},{"location":"api/json_pointer/pop_back/#examples","text":"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\" \"\"","title":"Examples"},{"location":"api/json_pointer/pop_back/#version-history","text":"Added in version 3.6.0.","title":"Version history"},{"location":"api/json_pointer/push_back/","text":"nlohmann::json_pointer:: push_back \u00b6 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 \u00b6 token (in) token to add Complexity \u00b6 Amortized constant. Examples \u00b6 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 \u00b6 Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.","title":"push_back"},{"location":"api/json_pointer/push_back/#nlohmannjson_pointerpush_back","text":"void push_back ( const string_t & token ); void push_back ( string_t && token ); Append an unescaped token at the end of the reference pointer.","title":"nlohmann::json_pointer::push_back"},{"location":"api/json_pointer/push_back/#parameters","text":"token (in) token to add","title":"Parameters"},{"location":"api/json_pointer/push_back/#complexity","text":"Amortized constant.","title":"Complexity"},{"location":"api/json_pointer/push_back/#examples","text":"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\"","title":"Examples"},{"location":"api/json_pointer/push_back/#version-history","text":"Added in version 3.6.0. Changed type of token to string_t in version 3.11.0.","title":"Version history"},{"location":"api/json_pointer/string_t/","text":"nlohmann::json_pointer:: string_t \u00b6 using string_t = RefStringType ; The string type used for the reference tokens making up the JSON pointer. See basic_json::string_t for more information. Examples \u00b6 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 < json :: json_pointer :: string_t , json :: string_t >:: value << std :: endl ; } Output: This is a s tr i n g. true Version history \u00b6 Added in version 3.11.0.","title":"string_t"},{"location":"api/json_pointer/string_t/#nlohmannjson_pointerstring_t","text":"using string_t = RefStringType ; The string type used for the reference tokens making up the JSON pointer. See basic_json::string_t for more information.","title":"nlohmann::json_pointer::string_t"},{"location":"api/json_pointer/string_t/#examples","text":"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 < json :: json_pointer :: string_t , json :: string_t >:: value << std :: endl ; } Output: This is a s tr i n g. true","title":"Examples"},{"location":"api/json_pointer/string_t/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/json_pointer/to_string/","text":"nlohmann::json_pointer:: to_string \u00b6 string_t to_string () const ; Return a string representation of the JSON pointer. Return value \u00b6 A string representation of the JSON pointer Notes \u00b6 For each JSON pointer ptr , it holds: ptr == json_pointer ( ptr . to_string ()); Examples \u00b6 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~ 0 n \" Version history \u00b6 Since version 2.0.0. Changed return type to string_t in version 3.11.0.","title":"to_string"},{"location":"api/json_pointer/to_string/#nlohmannjson_pointerto_string","text":"string_t to_string () const ; Return a string representation of the JSON pointer.","title":"nlohmann::json_pointer::to_string"},{"location":"api/json_pointer/to_string/#return-value","text":"A string representation of the JSON pointer","title":"Return value"},{"location":"api/json_pointer/to_string/#notes","text":"For each JSON pointer ptr , it holds: ptr == json_pointer ( ptr . to_string ());","title":"Notes"},{"location":"api/json_pointer/to_string/#examples","text":"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~ 0 n \"","title":"Examples"},{"location":"api/json_pointer/to_string/#version-history","text":"Since version 2.0.0. Changed return type to string_t in version 3.11.0.","title":"Version history"},{"location":"api/json_sax/","text":"nlohmann:: json_sax \u00b6 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 \u00b6 BasicJsonType a specialization of basic_json Member types \u00b6 number_integer_t - BasicJsonType 's type for numbers (integer) number_unsigned_t - BasicJsonType 's type for numbers (unsigned) number_float_t - BasicJsonType 's type for numbers (floating-point) string_t - BasicJsonType 's type for strings binary_t - BasicJsonType 's type for binary arrays Member functions \u00b6 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 \u00b6 Added in version 3.2.0. Support for binary values ( binary_t , binary ) added in version 3.8.0.","title":"Overview"},{"location":"api/json_sax/#nlohmannjson_sax","text":"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.","title":"nlohmann::json_sax"},{"location":"api/json_sax/#template-parameters","text":"BasicJsonType a specialization of basic_json","title":"Template parameters"},{"location":"api/json_sax/#member-types","text":"number_integer_t - BasicJsonType 's type for numbers (integer) number_unsigned_t - BasicJsonType 's type for numbers (unsigned) number_float_t - BasicJsonType 's type for numbers (floating-point) string_t - BasicJsonType 's type for strings binary_t - BasicJsonType 's type for binary arrays","title":"Member types"},{"location":"api/json_sax/#member-functions","text":"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","title":"Member functions"},{"location":"api/json_sax/#version-history","text":"Added in version 3.2.0. Support for binary values ( binary_t , binary ) added in version 3.8.0.","title":"Version history"},{"location":"api/json_sax/binary/","text":"nlohmann::json_sax:: binary \u00b6 virtual bool binary ( binary_t & val ) = 0 ; A binary value was read. Parameters \u00b6 val (in) binary value Return value \u00b6 Whether parsing should proceed. Notes \u00b6 It is safe to move the passed binary value. Examples \u00b6 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 < std :: string > 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 < std :: uint8_t > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: bi nar y(val= [ ... ] ) resul t : true Version history \u00b6 Added in version 3.8.0.","title":"binary"},{"location":"api/json_sax/binary/#nlohmannjson_saxbinary","text":"virtual bool binary ( binary_t & val ) = 0 ; A binary value was read.","title":"nlohmann::json_sax::binary"},{"location":"api/json_sax/binary/#parameters","text":"val (in) binary value","title":"Parameters"},{"location":"api/json_sax/binary/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/binary/#notes","text":"It is safe to move the passed binary value.","title":"Notes"},{"location":"api/json_sax/binary/#examples","text":"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 < std :: string > 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 < std :: uint8_t > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: bi nar y(val= [ ... ] ) resul t : true","title":"Examples"},{"location":"api/json_sax/binary/#version-history","text":"Added in version 3.8.0.","title":"Version history"},{"location":"api/json_sax/boolean/","text":"nlohmann::json_sax:: boolean \u00b6 virtual bool boolean ( bool val ) = 0 ; A boolean value was read. Parameters \u00b6 val (in) boolean value Return value \u00b6 Whether parsing should proceed. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"boolean"},{"location":"api/json_sax/boolean/#nlohmannjson_saxboolean","text":"virtual bool boolean ( bool val ) = 0 ; A boolean value was read.","title":"nlohmann::json_sax::boolean"},{"location":"api/json_sax/boolean/#parameters","text":"val (in) boolean value","title":"Parameters"},{"location":"api/json_sax/boolean/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/boolean/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/boolean/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/end_array/","text":"nlohmann::json_sax:: end_array \u00b6 virtual bool end_array () = 0 ; The end of an array was read. Return value \u00b6 Whether parsing should proceed. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"end_array"},{"location":"api/json_sax/end_array/#nlohmannjson_saxend_array","text":"virtual bool end_array () = 0 ; The end of an array was read.","title":"nlohmann::json_sax::end_array"},{"location":"api/json_sax/end_array/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/end_array/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/end_array/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/end_object/","text":"nlohmann::json_sax:: end_object \u00b6 virtual bool end_object () = 0 ; The end of an object was read. Return value \u00b6 Whether parsing should proceed. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"end_object"},{"location":"api/json_sax/end_object/#nlohmannjson_saxend_object","text":"virtual bool end_object () = 0 ; The end of an object was read.","title":"nlohmann::json_sax::end_object"},{"location":"api/json_sax/end_object/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/end_object/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/end_object/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/key/","text":"nlohmann::json_sax:: key \u00b6 virtual bool key ( string_t & val ) = 0 ; An object key was read. Parameters \u00b6 val (in) object key Return value \u00b6 Whether parsing should proceed. Notes \u00b6 It is safe to move the passed object key value. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"key"},{"location":"api/json_sax/key/#nlohmannjson_saxkey","text":"virtual bool key ( string_t & val ) = 0 ; An object key was read.","title":"nlohmann::json_sax::key"},{"location":"api/json_sax/key/#parameters","text":"val (in) object key","title":"Parameters"},{"location":"api/json_sax/key/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/key/#notes","text":"It is safe to move the passed object key value.","title":"Notes"},{"location":"api/json_sax/key/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/key/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/null/","text":"nlohmann::json_sax:: null \u00b6 virtual bool null () = 0 ; A null value was read. Return value \u00b6 Whether parsing should proceed. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"null"},{"location":"api/json_sax/null/#nlohmannjson_saxnull","text":"virtual bool null () = 0 ; A null value was read.","title":"nlohmann::json_sax::null"},{"location":"api/json_sax/null/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/null/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/null/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/number_float/","text":"nlohmann::json_sax:: number_float \u00b6 virtual bool number_float ( number_float_t val , const string_t & s ) = 0 ; A floating-point number was read. Parameters \u00b6 val (in) floating-point value s (in) string representation of the original input Return value \u00b6 Whether parsing should proceed. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"number_float"},{"location":"api/json_sax/number_float/#nlohmannjson_saxnumber_float","text":"virtual bool number_float ( number_float_t val , const string_t & s ) = 0 ; A floating-point number was read.","title":"nlohmann::json_sax::number_float"},{"location":"api/json_sax/number_float/#parameters","text":"val (in) floating-point value s (in) string representation of the original input","title":"Parameters"},{"location":"api/json_sax/number_float/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/number_float/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/number_float/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/number_integer/","text":"nlohmann::json_sax:: number_integer \u00b6 virtual bool number_integer ( number_integer_t val ) = 0 ; An integer number was read. Parameters \u00b6 val (in) integer value Return value \u00b6 Whether parsing should proceed. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"number_integer"},{"location":"api/json_sax/number_integer/#nlohmannjson_saxnumber_integer","text":"virtual bool number_integer ( number_integer_t val ) = 0 ; An integer number was read.","title":"nlohmann::json_sax::number_integer"},{"location":"api/json_sax/number_integer/#parameters","text":"val (in) integer value","title":"Parameters"},{"location":"api/json_sax/number_integer/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/number_integer/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/number_integer/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/number_unsigned/","text":"nlohmann::json_sax:: number_unsigned \u00b6 virtual bool number_unsigned ( number_unsigned_t val ) = 0 ; An unsigned integer number was read. Parameters \u00b6 val (in) unsigned integer value Return value \u00b6 Whether parsing should proceed. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"number_unsigned"},{"location":"api/json_sax/number_unsigned/#nlohmannjson_saxnumber_unsigned","text":"virtual bool number_unsigned ( number_unsigned_t val ) = 0 ; An unsigned integer number was read.","title":"nlohmann::json_sax::number_unsigned"},{"location":"api/json_sax/number_unsigned/#parameters","text":"val (in) unsigned integer value","title":"Parameters"},{"location":"api/json_sax/number_unsigned/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/number_unsigned/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/number_unsigned/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/parse_error/","text":"nlohmann::json_sax:: parse_error \u00b6 virtual bool parse_error ( std :: size_t position , const std :: string & last_token , const detail :: exception & ex ) = 0 ; A parse error occurred. Parameters \u00b6 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 \u00b6 Whether parsing should proceed ( must return false ). Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"parse_error"},{"location":"api/json_sax/parse_error/#nlohmannjson_saxparse_error","text":"virtual bool parse_error ( std :: size_t position , const std :: string & last_token , const detail :: exception & ex ) = 0 ; A parse error occurred.","title":"nlohmann::json_sax::parse_error"},{"location":"api/json_sax/parse_error/#parameters","text":"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","title":"Parameters"},{"location":"api/json_sax/parse_error/#return-value","text":"Whether parsing should proceed ( must return false ).","title":"Return value"},{"location":"api/json_sax/parse_error/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/parse_error/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/start_array/","text":"nlohmann::json_sax:: start_array \u00b6 virtual bool start_array ( std :: size_t elements ) = 0 ; The beginning of an array was read. Parameters \u00b6 elements (in) number of object elements or -1 if unknown Return value \u00b6 Whether parsing should proceed. Notes \u00b6 Binary formats may report the number of elements. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"start_array"},{"location":"api/json_sax/start_array/#nlohmannjson_saxstart_array","text":"virtual bool start_array ( std :: size_t elements ) = 0 ; The beginning of an array was read.","title":"nlohmann::json_sax::start_array"},{"location":"api/json_sax/start_array/#parameters","text":"elements (in) number of object elements or -1 if unknown","title":"Parameters"},{"location":"api/json_sax/start_array/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/start_array/#notes","text":"Binary formats may report the number of elements.","title":"Notes"},{"location":"api/json_sax/start_array/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/start_array/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/start_object/","text":"nlohmann::json_sax:: start_object \u00b6 virtual bool start_object ( std :: size_t elements ) = 0 ; The beginning of an object was read. Parameters \u00b6 elements (in) number of object elements or -1 if unknown Return value \u00b6 Whether parsing should proceed. Notes \u00b6 Binary formats may report the number of elements. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"start_object"},{"location":"api/json_sax/start_object/#nlohmannjson_saxstart_object","text":"virtual bool start_object ( std :: size_t elements ) = 0 ; The beginning of an object was read.","title":"nlohmann::json_sax::start_object"},{"location":"api/json_sax/start_object/#parameters","text":"elements (in) number of object elements or -1 if unknown","title":"Parameters"},{"location":"api/json_sax/start_object/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/start_object/#notes","text":"Binary formats may report the number of elements.","title":"Notes"},{"location":"api/json_sax/start_object/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/start_object/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/json_sax/string/","text":"nlohmann::json_sax:: string \u00b6 virtual bool string ( string_t & val ) = 0 ; A string value was read. Parameters \u00b6 val (in) string value Return value \u00b6 Whether parsing should proceed. Notes \u00b6 It is safe to move the passed string value. Examples \u00b6 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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false Version history \u00b6 Added in version 3.2.0.","title":"string"},{"location":"api/json_sax/string/#nlohmannjson_saxstring","text":"virtual bool string ( string_t & val ) = 0 ; A string value was read.","title":"nlohmann::json_sax::string"},{"location":"api/json_sax/string/#parameters","text":"val (in) string value","title":"Parameters"},{"location":"api/json_sax/string/#return-value","text":"Whether parsing should proceed.","title":"Return value"},{"location":"api/json_sax/string/#notes","text":"It is safe to move the passed string value.","title":"Notes"},{"location":"api/json_sax/string/#examples","text":"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 < std :: string > 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 << \" \\n result: \" << std :: boolalpha << result << std :: endl ; } Output: s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Image) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 800 ) key(val=Heigh t ) nu mber_u ns ig ne d(val= 600 ) key(val=Ti tle ) s tr i n g(val=View fr om 15 t h Floor) key(val=Thumb na il) s tart _objec t (eleme nts = 18446744073709551615 ) key(val=Url) s tr i n g(val=h tt p : //www.example.com/image/481989943) key(val=Heigh t ) nu mber_u ns ig ne d(val= 125 ) key(val=Wid t h) nu mber_u ns ig ne d(val= 100 ) e n d_objec t () key(val=A n ima te d) boolea n (val= false ) key(val=IDs) s tart _array(eleme nts = 18446744073709551615 ) nu mber_u ns ig ne d(val= 116 ) nu mber_u ns ig ne d(val= 943 ) nu mber_u ns ig ne d(val= 234 ) nu mber_i nte ger(val= -38793 ) e n d_array() key(val=Dele t io n Da te ) null () key(val=Dis tan ce) nu mber_ fl oa t (val= 12.723375 , s= 12.723374634 ) e n d_objec t () e n d_objec t () parse_error(posi t io n = 460 , las t _ t oke n = 12.723374634 } }], ex= [ jso n .excep t io n .parse_error. 101 ] parse error a t li ne 17 , colum n 6 : sy nta x error while parsi n g value - u ne xpec te d ' ] '; expec te d e n d o f i n pu t ) resul t : false","title":"Examples"},{"location":"api/json_sax/string/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/macros/","text":"Macros \u00b6 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 \u00b6 JSON_ASSERT(x) - control behavior of runtime assertions Exceptions \u00b6 JSON_CATCH_USER(exception) JSON_THROW_USER(exception) JSON_TRY_USER - control exceptions JSON_DIAGNOSTICS - control extended diagnostics JSON_NOEXCEPTION - switch off exceptions Language support \u00b6 JSON_HAS_CPP_11 JSON_HAS_CPP_14 JSON_HAS_CPP_17 JSON_HAS_CPP_20 - set supported C++ standard JSON_HAS_FILESYSTEM JSON_HAS_EXPERIMENTAL_FILESYSTEM - control std::filesystem support JSON_HAS_RANGES - control std::ranges support JSON_HAS_THREE_WAY_COMPARISON - control 3-way comparison support JSON_NO_IO - switch off functions relying on certain C++ I/O headers JSON_SKIP_UNSUPPORTED_COMPILER_CHECK - do not warn about unsupported compilers JSON_USE_GLOBAL_UDLS - place user-defined string literals (UDLs) into the global namespace Library version \u00b6 JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check NLOHMANN_JSON_VERSION_MAJOR NLOHMANN_JSON_VERSION_MINOR NLOHMANN_JSON_VERSION_PATCH - library version information Library namespace \u00b6 NLOHMANN_JSON_NAMESPACE - full name of the nlohmann namespace NLOHMANN_JSON_NAMESPACE_BEGIN NLOHMANN_JSON_NAMESPACE_END - open and close the library namespace NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the version component of the inline namespace Type conversions \u00b6 JSON_DISABLE_ENUM_SERIALIZATION - switch off default serialization/deserialization functions for enums JSON_USE_IMPLICIT_CONVERSIONS - control implicit conversions Comparison behavior \u00b6 JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - control comparison of discarded values Serialization/deserialization macros \u00b6 NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) - serialization/deserialization of types with access to private variables NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) - serialization/deserialization of types without access to private variables NLOHMANN_JSON_SERIALIZE_ENUM(type, ...) - serialization/deserialization of enum types","title":"Overview"},{"location":"api/macros/#macros","text":"Some aspects of the library can be configured by defining preprocessor macros before including the json.hpp header. See also the macro overview page .","title":"Macros"},{"location":"api/macros/#runtime-assertions","text":"JSON_ASSERT(x) - control behavior of runtime assertions","title":"Runtime assertions"},{"location":"api/macros/#exceptions","text":"JSON_CATCH_USER(exception) JSON_THROW_USER(exception) JSON_TRY_USER - control exceptions JSON_DIAGNOSTICS - control extended diagnostics JSON_NOEXCEPTION - switch off exceptions","title":"Exceptions"},{"location":"api/macros/#language-support","text":"JSON_HAS_CPP_11 JSON_HAS_CPP_14 JSON_HAS_CPP_17 JSON_HAS_CPP_20 - set supported C++ standard JSON_HAS_FILESYSTEM JSON_HAS_EXPERIMENTAL_FILESYSTEM - control std::filesystem support JSON_HAS_RANGES - control std::ranges support JSON_HAS_THREE_WAY_COMPARISON - control 3-way comparison support JSON_NO_IO - switch off functions relying on certain C++ I/O headers JSON_SKIP_UNSUPPORTED_COMPILER_CHECK - do not warn about unsupported compilers JSON_USE_GLOBAL_UDLS - place user-defined string literals (UDLs) into the global namespace","title":"Language support"},{"location":"api/macros/#library-version","text":"JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check NLOHMANN_JSON_VERSION_MAJOR NLOHMANN_JSON_VERSION_MINOR NLOHMANN_JSON_VERSION_PATCH - library version information","title":"Library version"},{"location":"api/macros/#library-namespace","text":"NLOHMANN_JSON_NAMESPACE - full name of the nlohmann namespace NLOHMANN_JSON_NAMESPACE_BEGIN NLOHMANN_JSON_NAMESPACE_END - open and close the library namespace NLOHMANN_JSON_NAMESPACE_NO_VERSION - disable the version component of the inline namespace","title":"Library namespace"},{"location":"api/macros/#type-conversions","text":"JSON_DISABLE_ENUM_SERIALIZATION - switch off default serialization/deserialization functions for enums JSON_USE_IMPLICIT_CONVERSIONS - control implicit conversions","title":"Type conversions"},{"location":"api/macros/#comparison-behavior","text":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - control comparison of discarded values","title":"Comparison behavior"},{"location":"api/macros/#serializationdeserialization-macros","text":"NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) - serialization/deserialization of types with access to private variables NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) - serialization/deserialization of types without access to private variables NLOHMANN_JSON_SERIALIZE_ENUM(type, ...) - serialization/deserialization of enum types","title":"Serialization/deserialization macros"},{"location":"api/macros/json_assert/","text":"JSON_ASSERT \u00b6 #define JSON_ASSERT(x) /* value */ This macro controls which code is executed for runtime assertions of the library. Parameters \u00b6 x (in) expression of scalar type Default definition \u00b6 The default value is assert ( x ) . #define JSON_ASSERT(x) assert(x) Therefore, assertions can be switched off by defining NDEBUG . Notes \u00b6 The library uses numerous assertions to guarantee invariants and to abort in case of otherwise undefined behavior (e.g., when calling operator[] with a missing object key on a const object). See page runtime assertions 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 \u00b6 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[] Version history \u00b6 Added in version 3.9.0.","title":"JSON_ASSERT"},{"location":"api/macros/json_assert/#json_assert","text":"#define JSON_ASSERT(x) /* value */ This macro controls which code is executed for runtime assertions of the library.","title":"JSON_ASSERT"},{"location":"api/macros/json_assert/#parameters","text":"x (in) expression of scalar type","title":"Parameters"},{"location":"api/macros/json_assert/#default-definition","text":"The default value is assert ( x ) . #define JSON_ASSERT(x) assert(x) Therefore, assertions can be switched off by defining NDEBUG .","title":"Default definition"},{"location":"api/macros/json_assert/#notes","text":"The library uses numerous assertions to guarantee invariants and to abort in case of otherwise undefined behavior (e.g., when calling operator[] with a missing object key on a const object). See page runtime assertions 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.","title":"Notes"},{"location":"api/macros/json_assert/#examples","text":"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[]","title":"Examples"},{"location":"api/macros/json_assert/#version-history","text":"Added in version 3.9.0.","title":"Version history"},{"location":"api/macros/json_diagnostics/","text":"JSON_DIAGNOSTICS \u00b6 #define JSON_DIAGNOSTICS /* value */ 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. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead. Default definition \u00b6 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 \u00b6 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 ( OFF by default) which defines JSON_DIAGNOSTICS accordingly. Examples \u00b6 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 ( 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 ( 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. Version history \u00b6 Added in version 3.10.0. As of version 3.11.0 the definition is allowed to vary between translation units.","title":"JSON_DIAGNOSTICS"},{"location":"api/macros/json_diagnostics/#json_diagnostics","text":"#define JSON_DIAGNOSTICS /* value */ 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. Note that enabling this macro increases the size of every JSON value by one pointer and adds some runtime overhead.","title":"JSON_DIAGNOSTICS"},{"location":"api/macros/json_diagnostics/#default-definition","text":"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.","title":"Default definition"},{"location":"api/macros/json_diagnostics/#notes","text":"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 ( OFF by default) which defines JSON_DIAGNOSTICS accordingly.","title":"Notes"},{"location":"api/macros/json_diagnostics/#examples","text":"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 ( 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 ( 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.","title":"Examples"},{"location":"api/macros/json_diagnostics/#version-history","text":"Added in version 3.10.0. As of version 3.11.0 the definition is allowed to vary between translation units.","title":"Version history"},{"location":"api/macros/json_disable_enum_serialization/","text":"JSON_DISABLE_ENUM_SERIALIZATION \u00b6 #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 (see arbitrary type conversions for more details). Parsing or serializing an enum will result in a compiler error. This works for both unscoped and scoped enums. Default definition \u00b6 The default value is 0 . #define JSON_DISABLE_ENUM_SERIALIZATION 0 Notes \u00b6 CMake option Enum serialization can also be controlled with the CMake option JSON_DisableEnumSerialization ( OFF by default) which defines JSON_DISABLE_ENUM_SERIALIZATION accordingly. Examples \u00b6 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 < Choice > (); } 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 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 < Choice > (); } 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 < std :: string > (); if ( value == \"first\" ) { ch = Choice :: first ; } else if ( value == \"second\" ) { ch = Choice :: second ; } } void to_json ( json & j , const Choice & ch ) { auto value = j . get < std :: string > (); if ( value == \"first\" ) { ch = Choice :: first ; } else if ( value == \"second\" ) { ch = Choice :: second ; } } int main () { // uses user-defined to_json function const json j = Choice :: first ; // uses user-defined from_json function Choice ch = j . get < Choice > (); } See also \u00b6 NLOHMANN_JSON_SERIALIZE_ENUM Version history \u00b6 Added in version 3.11.0.","title":"JSON_DISABLE_ENUM_SERIALIZATION"},{"location":"api/macros/json_disable_enum_serialization/#json_disable_enum_serialization","text":"#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 (see arbitrary type conversions for more details). Parsing or serializing an enum will result in a compiler error. This works for both unscoped and scoped enums.","title":"JSON_DISABLE_ENUM_SERIALIZATION"},{"location":"api/macros/json_disable_enum_serialization/#default-definition","text":"The default value is 0 . #define JSON_DISABLE_ENUM_SERIALIZATION 0","title":"Default definition"},{"location":"api/macros/json_disable_enum_serialization/#notes","text":"CMake option Enum serialization can also be controlled with the CMake option JSON_DisableEnumSerialization ( OFF by default) which defines JSON_DISABLE_ENUM_SERIALIZATION accordingly.","title":"Notes"},{"location":"api/macros/json_disable_enum_serialization/#examples","text":"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 < Choice > (); } 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 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 < Choice > (); } 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 < std :: string > (); if ( value == \"first\" ) { ch = Choice :: first ; } else if ( value == \"second\" ) { ch = Choice :: second ; } } void to_json ( json & j , const Choice & ch ) { auto value = j . get < std :: string > (); if ( value == \"first\" ) { ch = Choice :: first ; } else if ( value == \"second\" ) { ch = Choice :: second ; } } int main () { // uses user-defined to_json function const json j = Choice :: first ; // uses user-defined from_json function Choice ch = j . get < Choice > (); }","title":"Examples"},{"location":"api/macros/json_disable_enum_serialization/#see-also","text":"NLOHMANN_JSON_SERIALIZE_ENUM","title":"See also"},{"location":"api/macros/json_disable_enum_serialization/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/json_has_cpp_11/","text":"JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20 \u00b6 #define JSON_HAS_CPP_11 #define JSON_HAS_CPP_14 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_20 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 \u00b6 The default value is detected based on preprocessor macros such as __cplusplus , _HAS_CXX17 , or _MSVC_LANG . Notes \u00b6 JSON_HAS_CPP_11 is always defined. All macros are undefined outside the library. Examples \u00b6 Example The code below forces the library to use the C++14 standard: #define JSON_HAS_CPP_14 1 #include ... Version history \u00b6 Added in version 3.10.5.","title":"JSON_HAS_CPP_20"},{"location":"api/macros/json_has_cpp_11/#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20","text":"#define JSON_HAS_CPP_11 #define JSON_HAS_CPP_14 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_20 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.","title":"JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20"},{"location":"api/macros/json_has_cpp_11/#default-definition","text":"The default value is detected based on preprocessor macros such as __cplusplus , _HAS_CXX17 , or _MSVC_LANG .","title":"Default definition"},{"location":"api/macros/json_has_cpp_11/#notes","text":"JSON_HAS_CPP_11 is always defined. All macros are undefined outside the library.","title":"Notes"},{"location":"api/macros/json_has_cpp_11/#examples","text":"Example The code below forces the library to use the C++14 standard: #define JSON_HAS_CPP_14 1 #include ...","title":"Examples"},{"location":"api/macros/json_has_cpp_11/#version-history","text":"Added in version 3.10.5.","title":"Version history"},{"location":"api/macros/json_has_filesystem/","text":"JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM \u00b6 #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 . 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 . Default definition \u00b6 The default value is detected based on the preprocessor macros __cpp_lib_filesystem , __cpp_lib_experimental_filesystem , __has_include ( < filesystem > ) , or __has_include ( < experimental / filesystem > ) . Notes \u00b6 Note that older compilers or older versions of libstd++ also require the library stdc++fs to be linked to for filesystem support. Both macros are undefined outside the library. Examples \u00b6 Example The code below forces the library to use the header . #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #include ... Version history \u00b6 Added in version 3.10.5.","title":"JSON_HAS_FILESYSTEM"},{"location":"api/macros/json_has_filesystem/#json_has_filesystem-json_has_experimental_filesystem","text":"#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 . 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 .","title":"JSON_HAS_FILESYSTEM / JSON_HAS_EXPERIMENTAL_FILESYSTEM"},{"location":"api/macros/json_has_filesystem/#default-definition","text":"The default value is detected based on the preprocessor macros __cpp_lib_filesystem , __cpp_lib_experimental_filesystem , __has_include ( < filesystem > ) , or __has_include ( < experimental / filesystem > ) .","title":"Default definition"},{"location":"api/macros/json_has_filesystem/#notes","text":"Note that older compilers or older versions of libstd++ also require the library stdc++fs to be linked to for filesystem support. Both macros are undefined outside the library.","title":"Notes"},{"location":"api/macros/json_has_filesystem/#examples","text":"Example The code below forces the library to use the header . #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #include ...","title":"Examples"},{"location":"api/macros/json_has_filesystem/#version-history","text":"Added in version 3.10.5.","title":"Version history"},{"location":"api/macros/json_has_ranges/","text":"JSON_HAS_RANGES \u00b6 #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 \u00b6 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 \u00b6 Example The code below forces the library to enable support for ranges: #define JSON_HAS_RANGES 1 #include ... Version history \u00b6 Added in version 3.11.0.","title":"JSON_HAS_RANGES"},{"location":"api/macros/json_has_ranges/#json_has_ranges","text":"#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.","title":"JSON_HAS_RANGES"},{"location":"api/macros/json_has_ranges/#default-definition","text":"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.","title":"Default definition"},{"location":"api/macros/json_has_ranges/#examples","text":"Example The code below forces the library to enable support for ranges: #define JSON_HAS_RANGES 1 #include ...","title":"Examples"},{"location":"api/macros/json_has_ranges/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/json_has_three_way_comparison/","text":"JSON_HAS_THREE_WAY_COMPARISON \u00b6 #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 \u00b6 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 \u00b6 Example The code below forces the library to use 3-way comparison: #define JSON_HAS_THREE_WAY_COMPARISON 1 #include ... Version history \u00b6 Added in version 3.11.0.","title":"JSON_HAS_THREE_WAY_COMPARISON"},{"location":"api/macros/json_has_three_way_comparison/#json_has_three_way_comparison","text":"#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.","title":"JSON_HAS_THREE_WAY_COMPARISON"},{"location":"api/macros/json_has_three_way_comparison/#default-definition","text":"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.","title":"Default definition"},{"location":"api/macros/json_has_three_way_comparison/#examples","text":"Example The code below forces the library to use 3-way comparison: #define JSON_HAS_THREE_WAY_COMPARISON 1 #include ...","title":"Examples"},{"location":"api/macros/json_has_three_way_comparison/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/json_no_io/","text":"JSON_NO_IO \u00b6 #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 \u00b6 By default, JSON_NO_IO is not defined. #undef JSON_NO_IO Examples \u00b6 Example The code below forces the library not to use the headers , , , , and . #define JSON_NO_IO 1 #include ... Version history \u00b6 Added in version 3.10.0.","title":"JSON_NO_IO"},{"location":"api/macros/json_no_io/#json_no_io","text":"#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)).","title":"JSON_NO_IO"},{"location":"api/macros/json_no_io/#default-definition","text":"By default, JSON_NO_IO is not defined. #undef JSON_NO_IO","title":"Default definition"},{"location":"api/macros/json_no_io/#examples","text":"Example The code below forces the library not to use the headers , , , , and . #define JSON_NO_IO 1 #include ...","title":"Examples"},{"location":"api/macros/json_no_io/#version-history","text":"Added in version 3.10.0.","title":"Version history"},{"location":"api/macros/json_noexception/","text":"JSON_NOEXCEPTION \u00b6 #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 \u00b6 By default, the macro is not defined. #undef JSON_NOEXCEPTION Notes \u00b6 The explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824 . Examples \u00b6 Example The code below switches off exceptions in the library. #define JSON_NOEXCEPTION 1 #include ... See also \u00b6 Switch off exceptions for more information how to switch off exceptions Version history \u00b6 Added in version 2.1.0.","title":"JSON_NOEXCEPTION"},{"location":"api/macros/json_noexception/#json_noexception","text":"#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 .","title":"JSON_NOEXCEPTION"},{"location":"api/macros/json_noexception/#default-definition","text":"By default, the macro is not defined. #undef JSON_NOEXCEPTION","title":"Default definition"},{"location":"api/macros/json_noexception/#notes","text":"The explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824 .","title":"Notes"},{"location":"api/macros/json_noexception/#examples","text":"Example The code below switches off exceptions in the library. #define JSON_NOEXCEPTION 1 #include ...","title":"Examples"},{"location":"api/macros/json_noexception/#see-also","text":"Switch off exceptions for more information how to switch off exceptions","title":"See also"},{"location":"api/macros/json_noexception/#version-history","text":"Added in version 2.1.0.","title":"Version history"},{"location":"api/macros/json_skip_library_version_check/","text":"JSON_SKIP_LIBRARY_VERSION_CHECK \u00b6 #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 \u00b6 By default, the macro is not defined. #undef JSON_SKIP_LIBRARY_VERSION_CHECK Notes \u00b6 ABI compatibility Mixing different library versions in the same code can be a problem as the different versions may not be ABI compatible. Examples \u00b6 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 \u00b6 Added in version 3.11.0.","title":"JSON_SKIP_LIBRARY_VERSION_CHECK"},{"location":"api/macros/json_skip_library_version_check/#json_skip_library_version_check","text":"#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.","title":"JSON_SKIP_LIBRARY_VERSION_CHECK"},{"location":"api/macros/json_skip_library_version_check/#default-definition","text":"By default, the macro is not defined. #undef JSON_SKIP_LIBRARY_VERSION_CHECK","title":"Default definition"},{"location":"api/macros/json_skip_library_version_check/#notes","text":"ABI compatibility Mixing different library versions in the same code can be a problem as the different versions may not be ABI compatible.","title":"Notes"},{"location":"api/macros/json_skip_library_version_check/#examples","text":"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!","title":"Examples"},{"location":"api/macros/json_skip_library_version_check/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/json_skip_unsupported_compiler_check/","text":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK \u00b6 #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 to use the library with compilers that do not fully support C++11 and may only work if unsupported features are not used. Default definition \u00b6 By default, the macro is not defined. #undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK Examples \u00b6 Example The code below switches off the check whether the compiler is supported. #define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1 #include ... Version history \u00b6 Added in version 3.2.0.","title":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK"},{"location":"api/macros/json_skip_unsupported_compiler_check/#json_skip_unsupported_compiler_check","text":"#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 to use the library with compilers that do not fully support C++11 and may only work if unsupported features are not used.","title":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK"},{"location":"api/macros/json_skip_unsupported_compiler_check/#default-definition","text":"By default, the macro is not defined. #undef JSON_SKIP_UNSUPPORTED_COMPILER_CHECK","title":"Default definition"},{"location":"api/macros/json_skip_unsupported_compiler_check/#examples","text":"Example The code below switches off the check whether the compiler is supported. #define JSON_SKIP_UNSUPPORTED_COMPILER_CHECK 1 #include ...","title":"Examples"},{"location":"api/macros/json_skip_unsupported_compiler_check/#version-history","text":"Added in version 3.2.0.","title":"Version history"},{"location":"api/macros/json_throw_user/","text":"JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER \u00b6 // (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. This macro overrides 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 exceptions. The macro is always followed by a scope. 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. This macro overrides try calls inside the library. It has no arguments and is always followed by a scope. Parameters \u00b6 exception (in) an exception type Default definition \u00b6 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 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 \u00b6 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 \u00b6 Switch off exceptions for more information how to switch off exceptions JSON_NOEXCEPTION - switch off exceptions Version history \u00b6 Added in version 3.1.0.","title":"JSON_TRY_USER"},{"location":"api/macros/json_throw_user/#json_catch_user-json_throw_user-json_try_user","text":"// (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. This macro overrides 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 exceptions. The macro is always followed by a scope. 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. This macro overrides try calls inside the library. It has no arguments and is always followed by a scope.","title":"JSON_CATCH_USER, JSON_THROW_USER, JSON_TRY_USER"},{"location":"api/macros/json_throw_user/#parameters","text":"exception (in) an exception type","title":"Parameters"},{"location":"api/macros/json_throw_user/#default-definition","text":"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 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)","title":"Default definition"},{"location":"api/macros/json_throw_user/#examples","text":"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 ","title":"Examples"},{"location":"api/macros/json_throw_user/#see-also","text":"Switch off exceptions for more information how to switch off exceptions JSON_NOEXCEPTION - switch off exceptions","title":"See also"},{"location":"api/macros/json_throw_user/#version-history","text":"Added in version 3.1.0.","title":"Version history"},{"location":"api/macros/json_use_global_udls/","text":"JSON_USE_GLOBAL_UDLS \u00b6 #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 \u00b6 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 \u00b6 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 for details. CMake option The placement of user-defined string literals can also be controlled with the CMake option JSON_GlobalUDLs ( ON by default) which defines JSON_USE_GLOBAL_UDLS accordingly. Examples \u00b6 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 \u00b6 operator\"\"_json operator\"\"_json_pointer Version history \u00b6 Added in version 3.11.0.","title":"JSON_USE_GLOBAL_UDLS"},{"location":"api/macros/json_use_global_udls/#json_use_global_udls","text":"#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 .","title":"JSON_USE_GLOBAL_UDLS"},{"location":"api/macros/json_use_global_udls/#default-definition","text":"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.","title":"Default definition"},{"location":"api/macros/json_use_global_udls/#notes","text":"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 for details. CMake option The placement of user-defined string literals can also be controlled with the CMake option JSON_GlobalUDLs ( ON by default) which defines JSON_USE_GLOBAL_UDLS accordingly.","title":"Notes"},{"location":"api/macros/json_use_global_udls/#examples","text":"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","title":"Examples"},{"location":"api/macros/json_use_global_udls/#see-also","text":"operator\"\"_json operator\"\"_json_pointer","title":"See also"},{"location":"api/macros/json_use_global_udls/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/json_use_implicit_conversions/","text":"JSON_USE_IMPLICIT_CONVERSIONS \u00b6 #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 . Default definition \u00b6 By default, implicit conversions are enabled. #define JSON_USE_IMPLICIT_CONVERSIONS 1 Notes \u00b6 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 . CMake option Implicit conversions can also be controlled with the CMake option JSON_ImplicitConversions ( ON by default) which defines JSON_USE_IMPLICIT_CONVERSIONS accordingly. Examples \u00b6 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 < std :: string > (); See also \u00b6 operator ValueType - get a value (implicit) get - get a value (explicit) Version history \u00b6 Added in version 3.9.0.","title":"JSON_USE_IMPLICIT_CONVERSIONS"},{"location":"api/macros/json_use_implicit_conversions/#json_use_implicit_conversions","text":"#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 .","title":"JSON_USE_IMPLICIT_CONVERSIONS"},{"location":"api/macros/json_use_implicit_conversions/#default-definition","text":"By default, implicit conversions are enabled. #define JSON_USE_IMPLICIT_CONVERSIONS 1","title":"Default definition"},{"location":"api/macros/json_use_implicit_conversions/#notes","text":"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 . CMake option Implicit conversions can also be controlled with the CMake option JSON_ImplicitConversions ( ON by default) which defines JSON_USE_IMPLICIT_CONVERSIONS accordingly.","title":"Notes"},{"location":"api/macros/json_use_implicit_conversions/#examples","text":"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 < std :: string > ();","title":"Examples"},{"location":"api/macros/json_use_implicit_conversions/#see-also","text":"operator ValueType - get a value (implicit) get - get a value (explicit)","title":"See also"},{"location":"api/macros/json_use_implicit_conversions/#version-history","text":"Added in version 3.9.0.","title":"Version history"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/","text":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON \u00b6 #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 \u00b6 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 \u00b6 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<=> 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 ( OFF by default) which defines JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON accordingly. Examples \u00b6 Example The code below switches on the legacy discarded value comparison behavior in the library. #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 #include ... Version history \u00b6 Added in version 3.11.0.","title":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#json_use_legacy_discarded_value_comparison","text":"#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 .","title":"JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#default-definition","text":"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.","title":"Default definition"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#notes","text":"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<=> 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 ( OFF by default) which defines JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON accordingly.","title":"Notes"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#examples","text":"Example The code below switches on the legacy discarded value comparison behavior in the library. #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 #include ...","title":"Examples"},{"location":"api/macros/json_use_legacy_discarded_value_comparison/#version-history","text":"Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/nlohmann_define_type_intrusive/","text":"NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT \u00b6 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) // (1) #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) 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 , it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object. Will use value 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. Parameters \u00b6 type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the member variable to serialize/deserialize; up to 64 members can be given as comma-separated list Default definition \u00b6 The macros add two friend functions to the class which take care of the serialization and deserialization: friend void to_json ( nlohmann :: json & , const type & ); friend void from_json ( const nlohmann :: json & , type & ); See examples below for the concrete generated code. Notes \u00b6 Prerequisites The type type must be default constructible. See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation. The macro must be used inside the type (class/struct). Implementation limits The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json / from_json functions manually. The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported. Examples \u00b6 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( json :: exception & e ) { std :: cout << \"deserialization failed: \" << e . what () << std :: endl ; } } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } deserializa t io n fa iled : [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key 'age' n o t f ou n d 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_ ) {} friend void to_json ( nlohmann :: json & 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 ; } friend void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } rou n d tr ip : { \"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_ ) {} friend void to_json ( nlohmann :: json & 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 ; } friend void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Note how a default-initialized person object is used in the from_json to fill missing values. See also \u00b6 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT for a similar macro that can be defined outside the type. Arbitrary Type Conversions for an overview. Version history \u00b6 Added in version 3.9.0. Added in version 3.11.0.","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT"},{"location":"api/macros/nlohmann_define_type_intrusive/#nlohmann_define_type_intrusive-nlohmann_define_type_intrusive_with_default","text":"#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) // (1) #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) 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 , it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object. Will use value 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.","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE, NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT"},{"location":"api/macros/nlohmann_define_type_intrusive/#parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the member variable to serialize/deserialize; up to 64 members can be given as comma-separated list","title":"Parameters"},{"location":"api/macros/nlohmann_define_type_intrusive/#default-definition","text":"The macros add two friend functions to the class which take care of the serialization and deserialization: friend void to_json ( nlohmann :: json & , const type & ); friend void from_json ( const nlohmann :: json & , type & ); See examples below for the concrete generated code.","title":"Default definition"},{"location":"api/macros/nlohmann_define_type_intrusive/#notes","text":"Prerequisites The type type must be default constructible. See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation. The macro must be used inside the type (class/struct). Implementation limits The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json / from_json functions manually. The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported.","title":"Notes"},{"location":"api/macros/nlohmann_define_type_intrusive/#examples","text":"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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( json :: exception & e ) { std :: cout << \"deserialization failed: \" << e . what () << std :: endl ; } } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } deserializa t io n fa iled : [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key 'age' n o t f ou n d 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_ ) {} friend void to_json ( nlohmann :: json & 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 ; } friend void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } rou n d tr ip : { \"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_ ) {} friend void to_json ( nlohmann :: json & 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 ; } friend void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Note how a default-initialized person object is used in the from_json to fill missing values.","title":"Examples"},{"location":"api/macros/nlohmann_define_type_intrusive/#see-also","text":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE / NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT for a similar macro that can be defined outside the type. Arbitrary Type Conversions for an overview.","title":"See also"},{"location":"api/macros/nlohmann_define_type_intrusive/#version-history","text":"Added in version 3.9.0. Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/nlohmann_define_type_non_intrusive/","text":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT \u00b6 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) // (1) #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) 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 , it cannot access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object. Will use value 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. Parameters \u00b6 type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the (public) member variable to serialize/deserialize; up to 64 members can be given as comma-separated list Default definition \u00b6 The macros add two functions to the namespace which take care of the serialization and deserialization: void to_json ( nlohmann :: json & , const type & ); void from_json ( const nlohmann :: json & , type & ); See examples below for the concrete generated code. Notes \u00b6 Prerequisites The type type must be default constructible. See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation. The macro must be used outside the type (class/struct). The passed members must be public. Implementation limits The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json / from_json functions manually. The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported. Examples \u00b6 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( json :: exception & e ) { std :: cout << \"deserialization failed: \" << e . what () << std :: endl ; } } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } deserializa t io n fa iled : [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key 'age' n o t f ou n d 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 ; }; void to_json ( nlohmann :: json & 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 ; } void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } rou n d tr ip : { \"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_ ) {} }; void to_json ( nlohmann :: json & 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 ; } void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Note how a default-initialized person object is used in the from_json to fill missing values. See also \u00b6 NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT for a similar macro that can be defined inside the type. Arbitrary Type Conversions for an overview. Version history \u00b6 Added in version 3.9.0. Added in version 3.11.0.","title":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#nlohmann_define_type_non_intrusive-nlohmann_define_type_non_intrusive_with_default","text":"#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) // (1) #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) // (2) 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 , it cannot access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. Will use at during deserialization and will throw out_of_range.403 if a key is missing in the JSON object. Will use value 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.","title":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE, NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#parameters","text":"type (in) name of the type (class, struct) to serialize/deserialize member (in) name of the (public) member variable to serialize/deserialize; up to 64 members can be given as comma-separated list","title":"Parameters"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#default-definition","text":"The macros add two functions to the namespace which take care of the serialization and deserialization: void to_json ( nlohmann :: json & , const type & ); void from_json ( const nlohmann :: json & , type & ); See examples below for the concrete generated code.","title":"Default definition"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#notes","text":"Prerequisites The type type must be default constructible. See How can I use get() for non-default constructible/non-copyable types? for how to overcome this limitation. The macro must be used outside the type (class/struct). The passed members must be public. Implementation limits The current implementation is limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json / from_json functions manually. The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported.","title":"Notes"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#examples","text":"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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( json :: exception & e ) { std :: cout << \"deserialization failed: \" << e . what () << std :: endl ; } } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } deserializa t io n fa iled : [ jso n .excep t io n .ou t _o f _ra n ge. 403 ] key 'age' n o t f ou n d 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 ; }; void to_json ( nlohmann :: json & 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 ; } void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; try { auto p3 = j3 . get < ns :: person > (); } catch ( 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Output: serializa t io n : { \"address\" : \"744 Evergreen Terrace\" , \"age\" : 60 , \"name\" : \"Ned Flanders\" } rou n d tr ip : { \"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_ ) {} }; void to_json ( nlohmann :: json & 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 ; } void from_json ( const nlohmann :: json & 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 < ns :: person > (); // incomplete deserialization: json j3 = R \" ( {\"address\": \"742 Evergreen Terrace\", \"name\": \"Maggie Simpson\"} ) \" _json ; auto p3 = j3 . get < ns :: person > (); std :: cout << \"roundtrip: \" << json ( p3 ) << std :: endl ; } Note how a default-initialized person object is used in the from_json to fill missing values.","title":"Examples"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#see-also","text":"NLOHMANN_DEFINE_TYPE_INTRUSIVE / NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT for a similar macro that can be defined inside the type. Arbitrary Type Conversions for an overview.","title":"See also"},{"location":"api/macros/nlohmann_define_type_non_intrusive/#version-history","text":"Added in version 3.9.0. Added in version 3.11.0.","title":"Version history"},{"location":"api/macros/nlohmann_json_namespace/","text":"NLOHMANN_JSON_NAMESPACE \u00b6 #define NLOHMANN_JSON_NAMESPACE /* value */ This macro evaluates to the full name of the nlohmann namespace. Default definition \u00b6 The default value consists of the root namespace ( nlohmann ) and an inline ABI namespace. See nlohmann Namespace 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 \u00b6 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: nl ohma nn :: jso n _abi_v 3 _ 11 _ 2 See also \u00b6 NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_NO_VERSION Version history \u00b6 Added in version 3.11.0. Changed inline namespace name in version 3.11.2.","title":"NLOHMANN_JSON_NAMESPACE"},{"location":"api/macros/nlohmann_json_namespace/#nlohmann_json_namespace","text":"#define NLOHMANN_JSON_NAMESPACE /* value */ This macro evaluates to the full name of the nlohmann namespace.","title":"NLOHMANN_JSON_NAMESPACE"},{"location":"api/macros/nlohmann_json_namespace/#default-definition","text":"The default value consists of the root namespace ( nlohmann ) and an inline ABI namespace. See nlohmann Namespace 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.","title":"Default definition"},{"location":"api/macros/nlohmann_json_namespace/#examples","text":"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: nl ohma nn :: jso n _abi_v 3 _ 11 _ 2","title":"Examples"},{"location":"api/macros/nlohmann_json_namespace/#see-also","text":"NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_NO_VERSION","title":"See also"},{"location":"api/macros/nlohmann_json_namespace/#version-history","text":"Added in version 3.11.0. Changed inline namespace name in version 3.11.2.","title":"Version history"},{"location":"api/macros/nlohmann_json_namespace_begin/","text":"NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END \u00b6 #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 for details. Opens the namespace. Closes the namespace. Default definition \u00b6 The default definitions open and close the nlohmann namespace. The precise definition of [ NLOHMANN_JSON_NAMESPACE_BEGIN ] varies as described here . Default definition of NLOHMANN_JSON_NAMESPACE_BEGIN : namespace nlohmann { inline namespace json_abi_v3_11_2 { Default definition of NLOHMANN_JSON_NAMESPACE_END : } // namespace json_abi_v3_11_2 } // namespace nlohmann When these macros are not defined, the library will define them to their default definitions. Examples \u00b6 Example The example shows how to use NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END from the 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 < typename T > struct adl_serializer < std :: optional < T >> { static void to_json ( json & j , const std :: optional < T >& opt ) { if ( opt == std :: nullopt ) { j = nullptr ; } else { j = * opt ; } } }; NLOHMANN_JSON_NAMESPACE_END int main () { std :: optional < int > o1 = 1 ; std :: optional < int > 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 \u00b6 nlohmann Namespace NLOHMANN_JSON_NAMESPACE NLOHMANN_JSON_NAMESPACE_NO_VERSION Version history \u00b6 Added in version 3.11.0. Changed inline namespace name in version 3.11.2.","title":"NLOHMANN_JSON_NAMESPACE_END"},{"location":"api/macros/nlohmann_json_namespace_begin/#nlohmann_json_namespace_begin-nlohmann_json_namespace_end","text":"#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 for details. Opens the namespace. Closes the namespace.","title":"NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END"},{"location":"api/macros/nlohmann_json_namespace_begin/#default-definition","text":"The default definitions open and close the nlohmann namespace. The precise definition of [ NLOHMANN_JSON_NAMESPACE_BEGIN ] varies as described here . Default definition of NLOHMANN_JSON_NAMESPACE_BEGIN : namespace nlohmann { inline namespace json_abi_v3_11_2 { Default definition of NLOHMANN_JSON_NAMESPACE_END : } // namespace json_abi_v3_11_2 } // namespace nlohmann When these macros are not defined, the library will define them to their default definitions.","title":"Default definition"},{"location":"api/macros/nlohmann_json_namespace_begin/#examples","text":"Example The example shows how to use NLOHMANN_JSON_NAMESPACE_BEGIN / NLOHMANN_JSON_NAMESPACE_END from the 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 < typename T > struct adl_serializer < std :: optional < T >> { static void to_json ( json & j , const std :: optional < T >& opt ) { if ( opt == std :: nullopt ) { j = nullptr ; } else { j = * opt ; } } }; NLOHMANN_JSON_NAMESPACE_END int main () { std :: optional < int > o1 = 1 ; std :: optional < int > o2 = std :: nullopt ; NLOHMANN_JSON_NAMESPACE :: json j ; j . push_back ( o1 ); j . push_back ( o2 ); std :: cout << j << std :: endl ; } Output: [ 1 , null ]","title":"Examples"},{"location":"api/macros/nlohmann_json_namespace_begin/#see-also","text":"nlohmann Namespace NLOHMANN_JSON_NAMESPACE NLOHMANN_JSON_NAMESPACE_NO_VERSION","title":"See also"},{"location":"api/macros/nlohmann_json_namespace_begin/#version-history","text":"Added in version 3.11.0. Changed inline namespace name in version 3.11.2.","title":"Version history"},{"location":"api/macros/nlohmann_json_namespace_no_version/","text":"NLOHMANN_JSON_NAMESPACE_NO_VERSION \u00b6 #define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */ If defined to 1 , the version component is omitted from the inline namespace. See nlohmann Namespace for details. Default definition \u00b6 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 \u00b6 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: nl ohma nn :: jso n _abi See also \u00b6 nlohmann Namespace NLOHMANN_JSON_NAMESPACE NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END Version history \u00b6 Added in version 3.11.2.","title":"NLOHMANN_JSON_NAMESPACE_NO_VERSION"},{"location":"api/macros/nlohmann_json_namespace_no_version/#nlohmann_json_namespace_no_version","text":"#define NLOHMANN_JSON_NAMESPACE_NO_VERSION /* value */ If defined to 1 , the version component is omitted from the inline namespace. See nlohmann Namespace for details.","title":"NLOHMANN_JSON_NAMESPACE_NO_VERSION"},{"location":"api/macros/nlohmann_json_namespace_no_version/#default-definition","text":"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.","title":"Default definition"},{"location":"api/macros/nlohmann_json_namespace_no_version/#examples","text":"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: nl ohma nn :: jso n _abi","title":"Examples"},{"location":"api/macros/nlohmann_json_namespace_no_version/#see-also","text":"nlohmann Namespace NLOHMANN_JSON_NAMESPACE NLOHMANN_JSON_NAMESPACE_BEGIN, NLOHMANN_JSON_NAMESPACE_END","title":"See also"},{"location":"api/macros/nlohmann_json_namespace_no_version/#version-history","text":"Added in version 3.11.2.","title":"Version history"},{"location":"api/macros/nlohmann_json_serialize_enum/","text":"NLOHMANN_JSON_SERIALIZE_ENUM \u00b6 #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 de-serialized 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 \u00b6 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 \u00b6 The macros add two friend functions to the class which take care of the serialization and deserialization: template < typename BasicJsonType > inline void to_json ( BasicJsonType & j , const type & e ); template < typename BasicJsonType > inline void from_json ( const BasicJsonType & j , type & e ); Notes \u00b6 Prerequisites The macro must be used inside the namespace of the enum. Important notes When using get() , 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 \u00b6 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 < ns :: TaskState > (); auto blue = j_blue . get < ns :: Color > (); std :: cout << j_running << \" -> \" << running << \", \" << j_blue << \" -> \" << static_cast < int > ( 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 < ns :: TaskState > (); auto unknown = j_pi . get < ns :: Color > (); std :: cout << j_pi << \" -> \" << invalid << \", \" << j_pi << \" -> \" << static_cast < int > ( 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 < int > ( ns :: Color :: red ) << \" -> \" << j_red << std :: endl ; // deserialization json j_rot = \"rot\" ; auto rot = j_rot . get < ns :: Color > (); auto red = j_red . get < ns :: Color > (); std :: cout << j_rot << \" -> \" << static_cast < int > ( rot ) << std :: endl ; std :: cout << j_red << \" -> \" << static_cast < int > ( red ) << std :: endl ; } Output: 0 - > \"red\" \"rot\" - > 0 \"red\" - > 0 See also \u00b6 Specializing enum conversion JSON_DISABLE_ENUM_SERIALIZATION Version history \u00b6 Added in version 3.4.0.","title":"NLOHMANN_JSON_SERIALIZE_ENUM"},{"location":"api/macros/nlohmann_json_serialize_enum/#nlohmann_json_serialize_enum","text":"#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 de-serialized 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.","title":"NLOHMANN_JSON_SERIALIZE_ENUM"},{"location":"api/macros/nlohmann_json_serialize_enum/#parameters","text":"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","title":"Parameters"},{"location":"api/macros/nlohmann_json_serialize_enum/#default-definition","text":"The macros add two friend functions to the class which take care of the serialization and deserialization: template < typename BasicJsonType > inline void to_json ( BasicJsonType & j , const type & e ); template < typename BasicJsonType > inline void from_json ( const BasicJsonType & j , type & e );","title":"Default definition"},{"location":"api/macros/nlohmann_json_serialize_enum/#notes","text":"Prerequisites The macro must be used inside the namespace of the enum. Important notes When using get() , 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.","title":"Notes"},{"location":"api/macros/nlohmann_json_serialize_enum/#examples","text":"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 < ns :: TaskState > (); auto blue = j_blue . get < ns :: Color > (); std :: cout << j_running << \" -> \" << running << \", \" << j_blue << \" -> \" << static_cast < int > ( 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 < ns :: TaskState > (); auto unknown = j_pi . get < ns :: Color > (); std :: cout << j_pi << \" -> \" << invalid << \", \" << j_pi << \" -> \" << static_cast < int > ( 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 < int > ( ns :: Color :: red ) << \" -> \" << j_red << std :: endl ; // deserialization json j_rot = \"rot\" ; auto rot = j_rot . get < ns :: Color > (); auto red = j_red . get < ns :: Color > (); std :: cout << j_rot << \" -> \" << static_cast < int > ( rot ) << std :: endl ; std :: cout << j_red << \" -> \" << static_cast < int > ( red ) << std :: endl ; } Output: 0 - > \"red\" \"rot\" - > 0 \"red\" - > 0","title":"Examples"},{"location":"api/macros/nlohmann_json_serialize_enum/#see-also","text":"Specializing enum conversion JSON_DISABLE_ENUM_SERIALIZATION","title":"See also"},{"location":"api/macros/nlohmann_json_serialize_enum/#version-history","text":"Added in version 3.4.0.","title":"Version history"},{"location":"api/macros/nlohmann_json_version_major/","text":"NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH \u00b6 #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 . Default definition \u00b6 The macros are defined according to the current library version. Examples \u00b6 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 f or Moder n C++ versio n 3.11.2 See also \u00b6 meta - returns version information on the library JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check Version history \u00b6 Added in version 3.1.0.","title":"NLOHMANN_JSON_VERSION_PATCH"},{"location":"api/macros/nlohmann_json_version_major/#nlohmann_json_version_major-nlohmann_json_version_minor-nlohmann_json_version_patch","text":"#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 .","title":"NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH"},{"location":"api/macros/nlohmann_json_version_major/#default-definition","text":"The macros are defined according to the current library version.","title":"Default definition"},{"location":"api/macros/nlohmann_json_version_major/#examples","text":"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 f or Moder n C++ versio n 3.11.2","title":"Examples"},{"location":"api/macros/nlohmann_json_version_major/#see-also","text":"meta - returns version information on the library JSON_SKIP_LIBRARY_VERSION_CHECK - skip library version check","title":"See also"},{"location":"api/macros/nlohmann_json_version_major/#version-history","text":"Added in version 3.1.0.","title":"Version history"},{"location":"features/arbitrary_types/","text":"Arbitrary Type Conversions \u00b6 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 < std :: string > (), j [ \"address\" ]. get < std :: string > (), j [ \"age\" ]. get < int > () }; 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 < ns :: person > (); // that's it assert ( p == p2 ); Basic usage \u00b6 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 issue 1108 for errors that may occur otherwise. When using get() , your_type MUST be DefaultConstructible . (There is a way to bypass this requirement described later.) In function from_json , use function at() 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 \u00b6 If you just want to serialize/deserialize some structs, the to_json / from_json functions can be a lot of boilerplate. There are four macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object: NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...) is to be defined inside the namespace of the class/struct to create code for. It will throw an exception in from_json() due to a missing value in the JSON object. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...) is to be defined inside the namespace of the class/struct to create code for. It will not throw an exception in from_json() due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type. NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...) is to be defined inside the class/struct to create code for. This macro can also access private members. It will throw an exception in from_json() due to a missing value in the JSON object. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...) is to be defined inside the class/struct to create code for. This macro can also access private members. It will not throw an exception in from_json() due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type. In all macros, the first parameter is the name of the class/struct, and all remaining parameters name the members. You can read more docs about them starting from here . Implementation limits The current macro implementations are limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json / from_json functions manually. The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported. 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 ) } Here is an 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 ) }; } How do I convert third-party types? \u00b6 This requires a bit more advanced technique. But first, let's 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 ). It is implemented like this (simplified): template < typename T > 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 < typename T > struct adl_serializer < boost :: optional < T >> { static void to_json ( json & j , const boost :: optional < T >& 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 < T >& opt ) { if ( j . is_null ()) { opt = boost :: none ; } else { opt = j . get < T > (); // same as above, but with // adl_serializer::from_json } } }; NLOHMANN_JSON_NAMESPACE_END ABI compatibility Use NLOHMANN_JSON_NAMESPACE_BEGIN 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? \u00b6 There is a way, if your type is 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 < move_only_type > { // 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 < int > ()}; } // 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) \u00b6 Yes. You might want to take a look at unit-udt.cpp in the test suite, to see a few examples. If you write your own serializer, you'll 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 < typename T , typename SFINAE = typename std :: enable_if < sizeof ( T ) <= 32 >:: type > struct less_than_32_serializer { template < typename BasicJsonType > 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 < typename BasicJsonType > 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 < typename T , void > struct bad_serializer { template < typename BasicJsonType > 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 < typename BasicJsonType > static void to_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 < T > (); // oops! } };","title":"Arbitrary Type Conversions"},{"location":"features/arbitrary_types/#arbitrary-type-conversions","text":"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 < std :: string > (), j [ \"address\" ]. get < std :: string > (), j [ \"age\" ]. get < int > () }; 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 < ns :: person > (); // that's it assert ( p == p2 );","title":"Arbitrary Type Conversions"},{"location":"features/arbitrary_types/#basic-usage","text":"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 issue 1108 for errors that may occur otherwise. When using get() , your_type MUST be DefaultConstructible . (There is a way to bypass this requirement described later.) In function from_json , use function at() 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.","title":"Basic usage"},{"location":"features/arbitrary_types/#simplify-your-life-with-macros","text":"If you just want to serialize/deserialize some structs, the to_json / from_json functions can be a lot of boilerplate. There are four macros to make your life easier as long as you (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object: NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...) is to be defined inside the namespace of the class/struct to create code for. It will throw an exception in from_json() due to a missing value in the JSON object. NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...) is to be defined inside the namespace of the class/struct to create code for. It will not throw an exception in from_json() due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type. NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...) is to be defined inside the class/struct to create code for. This macro can also access private members. It will throw an exception in from_json() due to a missing value in the JSON object. NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(name, member1, member2, ...) is to be defined inside the class/struct to create code for. This macro can also access private members. It will not throw an exception in from_json() due to a missing value in the JSON object, but fills in values from object which is default-constructed by the type. In all macros, the first parameter is the name of the class/struct, and all remaining parameters name the members. You can read more docs about them starting from here . Implementation limits The current macro implementations are limited to at most 64 member variables. If you want to serialize/deserialize types with more than 64 member variables, you need to define the to_json / from_json functions manually. The macros only work for the nlohmann::json type; other specializations such as nlohmann::ordered_json are currently unsupported. 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 ) } Here is an 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 ) }; }","title":"Simplify your life with macros"},{"location":"features/arbitrary_types/#how-do-i-convert-third-party-types","text":"This requires a bit more advanced technique. But first, let's 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 ). It is implemented like this (simplified): template < typename T > 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 < typename T > struct adl_serializer < boost :: optional < T >> { static void to_json ( json & j , const boost :: optional < T >& 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 < T >& opt ) { if ( j . is_null ()) { opt = boost :: none ; } else { opt = j . get < T > (); // same as above, but with // adl_serializer::from_json } } }; NLOHMANN_JSON_NAMESPACE_END ABI compatibility Use NLOHMANN_JSON_NAMESPACE_BEGIN and NLOHMANN_JSON_NAMESPACE_END instead of namespace nlohmann { } in code which may be linked with different versions of this library.","title":"How do I convert third-party types?"},{"location":"features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types","text":"There is a way, if your type is 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 < move_only_type > { // 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 < int > ()}; } // 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 ; } }; }","title":"How can I use get() for non-default constructible/non-copyable types?"},{"location":"features/arbitrary_types/#can-i-write-my-own-serializer-advanced-use","text":"Yes. You might want to take a look at unit-udt.cpp in the test suite, to see a few examples. If you write your own serializer, you'll 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 < typename T , typename SFINAE = typename std :: enable_if < sizeof ( T ) <= 32 >:: type > struct less_than_32_serializer { template < typename BasicJsonType > 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 < typename BasicJsonType > 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 < typename T , void > struct bad_serializer { template < typename BasicJsonType > 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 < typename BasicJsonType > static void to_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 < T > (); // oops! } };","title":"Can I write my own serializer? (Advanced use)"},{"location":"features/assertions/","text":"Runtime Assertions \u00b6 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 of, the latter checks for undefined behavior are to detect bugs in client code. Switch off runtime assertions \u00b6 Runtime assertions can be switched off by defining the preprocessor macro NDEBUG (see the documentation of assert ) which is the default for release builds. Change assertion behavior \u00b6 The behavior of runtime assertions can be changes by defining macro JSON_ASSERT(x) before including the json.hpp header. Function with runtime assertions \u00b6 Unchecked object access to a const value \u00b6 Function operator[] implements unchecked access for objects. Whereas a missing key is added in 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 or call the contains function before. See also the documentation on element access . 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 \u00b6 Constructing a JSON value from an iterator range (see constructor ) 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 \u00b6 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. Reading from a null FILE pointer \u00b6 Reading from a null FILE pointer is undefined behavior and yields a runtime assertion. This can happen when calling std :: fopen on a nonexistent file. Example 4: Uninitialized iterator The following code will trigger an assertion at runtime: #include using json = nlohmann :: json ; int main () { std :: FILE * f = std :: fopen ( \"nonexistent_file.json\" , \"r\" ); json j = json :: parse ( f ); } Output: Assertion failed: (m_file != nullptr), function file_input_adapter, file input_adapters.hpp, line 55.","title":"Runtime Assertions"},{"location":"features/assertions/#runtime-assertions","text":"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 of, the latter checks for undefined behavior are to detect bugs in client code.","title":"Runtime Assertions"},{"location":"features/assertions/#switch-off-runtime-assertions","text":"Runtime assertions can be switched off by defining the preprocessor macro NDEBUG (see the documentation of assert ) which is the default for release builds.","title":"Switch off runtime assertions"},{"location":"features/assertions/#change-assertion-behavior","text":"The behavior of runtime assertions can be changes by defining macro JSON_ASSERT(x) before including the json.hpp header.","title":"Change assertion behavior"},{"location":"features/assertions/#function-with-runtime-assertions","text":"","title":"Function with runtime assertions"},{"location":"features/assertions/#unchecked-object-access-to-a-const-value","text":"Function operator[] implements unchecked access for objects. Whereas a missing key is added in 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 or call the contains function before. See also the documentation on element access . 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.","title":"Unchecked object access to a const value"},{"location":"features/assertions/#constructing-from-an-uninitialized-iterator-range","text":"Constructing a JSON value from an iterator range (see constructor ) 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.","title":"Constructing from an uninitialized iterator range"},{"location":"features/assertions/#operations-on-uninitialized-iterators","text":"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.","title":"Operations on uninitialized iterators"},{"location":"features/assertions/#reading-from-a-null-file-pointer","text":"Reading from a null FILE pointer is undefined behavior and yields a runtime assertion. This can happen when calling std :: fopen on a nonexistent file. Example 4: Uninitialized iterator The following code will trigger an assertion at runtime: #include using json = nlohmann :: json ; int main () { std :: FILE * f = std :: fopen ( \"nonexistent_file.json\" , \"r\" ); json j = json :: parse ( f ); } Output: Assertion failed: (m_file != nullptr), function file_input_adapter, file input_adapters.hpp, line 55.","title":"Reading from a null FILE pointer"},{"location":"features/binary_values/","text":"Binary Values \u00b6 The library implements several binary formats that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics define 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 \u00b6 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 true 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 \u00b6 Binary values are serialized differently according to the formats. JSON \u00b6 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 \u00b6 BJData neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library. 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 UBJSON: // convert to UBJSON 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 UBJSON has no binary type , and deserializing v would yield the following value: { \"binary\" : [ 202 , 254 , 186 , 190 ] } BSON \u00b6 BSON supports binary values and subtypes. If a subtype is given, it is used and added as 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 \u00b6 CBOR 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 \u00b6 MessagePack 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 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 \u00b6 UBJSON neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library. 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 ] }","title":"Binary Values"},{"location":"features/binary_values/#binary-values","text":"The library implements several binary formats that encode JSON in an efficient way. Most of these formats support binary values; that is, values that have semantics define 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.","title":"Binary Values"},{"location":"features/binary_values/#api-for-binary-values","text":"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 true 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","title":"API for binary values"},{"location":"features/binary_values/#serialization","text":"Binary values are serialized differently according to the formats.","title":"Serialization"},{"location":"features/binary_values/#json","text":"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.","title":"JSON"},{"location":"features/binary_values/#bjdata","text":"BJData neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library. 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 UBJSON: // convert to UBJSON 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 UBJSON has no binary type , and deserializing v would yield the following value: { \"binary\" : [ 202 , 254 , 186 , 190 ] }","title":"BJData"},{"location":"features/binary_values/#bson","text":"BSON supports binary values and subtypes. If a subtype is given, it is used and added as 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 } }","title":"BSON"},{"location":"features/binary_values/#cbor","text":"CBOR 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 } }","title":"CBOR"},{"location":"features/binary_values/#messagepack","text":"MessagePack 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 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 } }","title":"MessagePack"},{"location":"features/binary_values/#ubjson","text":"UBJSON neither supports binary values nor subtypes, and proposes to serialize binary values as array of uint8 values. This translation is implemented by the library. 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 ] }","title":"UBJSON"},{"location":"features/comments/","text":"Comments \u00b6 This library does not support comments by default . It does so for three reasons: Comments are not part of the JSON specification . You may argue that // or /* */ are allowed in JavaScript, but JSON is not JavaScript. This was not an oversight: Douglas Crockford wrote on this 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. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check The Harmful Consequences of the Robustness Principle on this. However, you can pass set parameter ignore_comments to true in the parse function to ignore // or /* */ comments. Comments will then be treated as whitespace. 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 \"json.hpp\" 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\" ] }","title":"Comments"},{"location":"features/comments/#comments","text":"This library does not support comments by default . It does so for three reasons: Comments are not part of the JSON specification . You may argue that // or /* */ are allowed in JavaScript, but JSON is not JavaScript. This was not an oversight: Douglas Crockford wrote on this 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. It is dangerous for interoperability if some libraries would add comment support while others don't. Please check The Harmful Consequences of the Robustness Principle on this. However, you can pass set parameter ignore_comments to true in the parse function to ignore // or /* */ comments. Comments will then be treated as whitespace. 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 \"json.hpp\" 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\" ] }","title":"Comments"},{"location":"features/enum_conversion/","text":"Specializing enum conversion \u00b6 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 de-serialized JSON data may be undefined or a different enum value than was originally intended. 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 declares a set of to_json() / from_json() functions for type TaskState while avoiding repetition and boilerplate serialization code. Usage \u00b6 // enum to JSON as string json j = TS_STOPPED ; assert ( j == \"stopped\" ); // json string to enum json j3 = \"running\" ; assert ( j3 . get < TaskState > () == TS_RUNNING ); // 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 \u00b6 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() , undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. 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 .","title":"Specializing enum conversion"},{"location":"features/enum_conversion/#specializing-enum-conversion","text":"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 de-serialized JSON data may be undefined or a different enum value than was originally intended. 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 declares a set of to_json() / from_json() functions for type TaskState while avoiding repetition and boilerplate serialization code.","title":"Specializing enum conversion"},{"location":"features/enum_conversion/#usage","text":"// enum to JSON as string json j = TS_STOPPED ; assert ( j == \"stopped\" ); // json string to enum json j3 = \"running\" ; assert ( j3 . get < TaskState > () == TS_RUNNING ); // undefined json value to enum (where the first map entry above is the default) json jPi = 3.14 ; assert ( jPi . get < TaskState > () == TS_INVALID );","title":"Usage"},{"location":"features/enum_conversion/#notes","text":"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() , undefined JSON values will default to the first pair specified in your map. Select this default pair carefully. 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 .","title":"Notes"},{"location":"features/iterators/","text":"Iterators \u00b6 Overview \u00b6 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 \u00b6 When iterating over objects, values are ordered with respect to the object_comparator_t type which defaults to std::less . See the types documentation 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 key during iteration \u00b6 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 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: o ne : 1 t hree : 3 t wo : 2 Range-based for loops \u00b6 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 https://github.com/nlohmann/json/issues/2040 for more information. Reverse iteration order \u00b6 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 \u00b6 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 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 \u00b6 Operations invalidated iterators clear all","title":"Iterators"},{"location":"features/iterators/#iterators","text":"","title":"Iterators"},{"location":"features/iterators/#overview","text":"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() .","title":"Overview"},{"location":"features/iterators/#iteration-order-for-objects","text":"When iterating over objects, values are ordered with respect to the object_comparator_t type which defaults to std::less . See the types documentation 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\".","title":"Iteration order for objects"},{"location":"features/iterators/#access-object-key-during-iteration","text":"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 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: o ne : 1 t hree : 3 t wo : 2","title":"Access object key during iteration"},{"location":"features/iterators/#range-based-for-loops","text":"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 https://github.com/nlohmann/json/issues/2040 for more information.","title":"Range-based for loops"},{"location":"features/iterators/#reverse-iteration-order","text":"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","title":"Reverse iteration order"},{"location":"features/iterators/#iterating-strings-and-binary-values","text":"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 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\"","title":"Iterating strings and binary values"},{"location":"features/iterators/#iterator-invalidation","text":"Operations invalidated iterators clear all","title":"Iterator invalidation"},{"location":"features/json_patch/","text":"JSON Patch and Diff \u00b6 Patches \u00b6 JSON Patch ( RFC 6902 ) 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 \u00b6 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\" ] }","title":"JSON Patch and Diff"},{"location":"features/json_patch/#json-patch-and-diff","text":"","title":"JSON Patch and Diff"},{"location":"features/json_patch/#patches","text":"JSON Patch ( RFC 6902 ) 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\" ] }","title":"Patches"},{"location":"features/json_patch/#diff","text":"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\" ] }","title":"Diff"},{"location":"features/json_pointer/","text":"JSON Pointer \u00b6 Introduction \u00b6 The library supports JSON Pointer ( RFC 6901 ) as 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 for more information. JSON Pointer creation \u00b6 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 are implemented. See the constructor documentation for more information. Value access \u00b6 JSON Pointers can be used in the at , operator[] , and value 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 \u00b6 The library implements a function flatten 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 recreates the original value. auto j_original = j_flat . unflatten (); See also \u00b6 Class json_pointer Function flatten Function unflatten JSON Patch","title":"JSON Pointer"},{"location":"features/json_pointer/#json-pointer","text":"","title":"JSON Pointer"},{"location":"features/json_pointer/#introduction","text":"The library supports JSON Pointer ( RFC 6901 ) as 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 for more information.","title":"Introduction"},{"location":"features/json_pointer/#json-pointer-creation","text":"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 are implemented. See the constructor documentation for more information.","title":"JSON Pointer creation"},{"location":"features/json_pointer/#value-access","text":"JSON Pointers can be used in the at , operator[] , and value 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","title":"Value access"},{"location":"features/json_pointer/#flatten-unflatten","text":"The library implements a function flatten 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 recreates the original value. auto j_original = j_flat . unflatten ();","title":"Flatten / unflatten"},{"location":"features/json_pointer/#see-also","text":"Class json_pointer Function flatten Function unflatten JSON Patch","title":"See also"},{"location":"features/macros/","text":"Supported Macros \u00b6 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) \u00b6 This macro controls which code is executed for runtime assertions of the library. See full documentation of JSON_ASSERT(x) . JSON_CATCH_USER(exception) \u00b6 This macro overrides catch calls inside the library. See full documentation of JSON_CATCH_USER(exception) . JSON_DIAGNOSTICS \u00b6 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_HAS_CPP_11 , JSON_HAS_CPP_14 , JSON_HAS_CPP_17 , JSON_HAS_CPP_20 \u00b6 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 , and JSON_HAS_CPP_20 . JSON_HAS_FILESYSTEM , JSON_HAS_EXPERIMENTAL_FILESYSTEM \u00b6 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 . JSON_NOEXCEPTION \u00b6 Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION . See full documentation of JSON_NOEXCEPTION . JSON_DISABLE_ENUM_SERIALIZATION \u00b6 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 \u00b6 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 . JSON_SKIP_LIBRARY_VERSION_CHECK \u00b6 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 \u00b6 When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows to use 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) \u00b6 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 \u00b6 This macro overrides try calls inside the library. See full documentation of JSON_TRY_USER . JSON_USE_IMPLICIT_CONVERSIONS \u00b6 When defined to 0 , implicit conversions are switched off. By default, implicit conversions are switched on. See full documentation of JSON_USE_IMPLICIT_CONVERSIONS . NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...) \u00b6 This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) 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 , it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. See full documentation of NLOHMANN_DEFINE_TYPE_INTRUSIVE . NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...) \u00b6 This macro is similar to NLOHMANN_DEFINE_TYPE_INTRUSIVE . It will not throw an exception in from_json() due to a missing value in the JSON object, but can throw due to a mismatched type. The from_json() function default constructs an object and uses its values as the defaults when calling the value function. See full documentation of NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT . NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...) \u00b6 This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object. The macro is to be defined inside the namespace of the class/struct to create code for. Private members cannot be accessed. Use NLOHMANN_DEFINE_TYPE_INTRUSIVE in these scenarios. The first parameter is the name of the class/struct, and all remaining parameters name the members. See full documentation of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE . NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...) \u00b6 This macro is similar to NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE . It will not throw an exception in from_json() due to a missing value in the JSON object, but can throw due to a mismatched type. The from_json() function default constructs an object and uses its values as the defaults when calling the value function. See full documentation of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT . NLOHMANN_JSON_SERIALIZE_ENUM(type, ...) \u00b6 This macro simplifies the serialization/deserialization of enum types. See Specializing enum conversion for more information. See full documentation of NLOHMANN_JSON_SERIALIZE_ENUM . NLOHMANN_JSON_VERSION_MAJOR , NLOHMANN_JSON_VERSION_MINOR , NLOHMANN_JSON_VERSION_PATCH \u00b6 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 .","title":"Supported Macros"},{"location":"features/macros/#supported-macros","text":"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.","title":"Supported Macros"},{"location":"features/macros/#json_assertx","text":"This macro controls which code is executed for runtime assertions of the library. See full documentation of JSON_ASSERT(x) .","title":"JSON_ASSERT(x)"},{"location":"features/macros/#json_catch_userexception","text":"This macro overrides catch calls inside the library. See full documentation of JSON_CATCH_USER(exception) .","title":"JSON_CATCH_USER(exception)"},{"location":"features/macros/#json_diagnostics","text":"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 .","title":"JSON_DIAGNOSTICS"},{"location":"features/macros/#json_has_cpp_11-json_has_cpp_14-json_has_cpp_17-json_has_cpp_20","text":"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 , and JSON_HAS_CPP_20 .","title":"JSON_HAS_CPP_11, JSON_HAS_CPP_14, JSON_HAS_CPP_17, JSON_HAS_CPP_20"},{"location":"features/macros/#json_has_filesystem-json_has_experimental_filesystem","text":"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 .","title":"JSON_HAS_FILESYSTEM, JSON_HAS_EXPERIMENTAL_FILESYSTEM"},{"location":"features/macros/#json_noexception","text":"Exceptions can be switched off by defining the symbol JSON_NOEXCEPTION . See full documentation of JSON_NOEXCEPTION .","title":"JSON_NOEXCEPTION"},{"location":"features/macros/#json_disable_enum_serialization","text":"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 .","title":"JSON_DISABLE_ENUM_SERIALIZATION"},{"location":"features/macros/#json_no_io","text":"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 .","title":"JSON_NO_IO"},{"location":"features/macros/#json_skip_library_version_check","text":"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 .","title":"JSON_SKIP_LIBRARY_VERSION_CHECK"},{"location":"features/macros/#json_skip_unsupported_compiler_check","text":"When defined, the library will not create a compile error when a known unsupported compiler is detected. This allows to use 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 .","title":"JSON_SKIP_UNSUPPORTED_COMPILER_CHECK"},{"location":"features/macros/#json_throw_userexception","text":"This macro overrides throw calls inside the library. The argument is the exception to be thrown. See full documentation of JSON_THROW_USER(exception) .","title":"JSON_THROW_USER(exception)"},{"location":"features/macros/#json_try_user","text":"This macro overrides try calls inside the library. See full documentation of JSON_TRY_USER .","title":"JSON_TRY_USER"},{"location":"features/macros/#json_use_implicit_conversions","text":"When defined to 0 , implicit conversions are switched off. By default, implicit conversions are switched on. See full documentation of JSON_USE_IMPLICIT_CONVERSIONS .","title":"JSON_USE_IMPLICIT_CONVERSIONS"},{"location":"features/macros/#nlohmann_define_type_intrusivetype-member","text":"This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) 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 , it can access private members. The first parameter is the name of the class/struct, and all remaining parameters name the members. See full documentation of NLOHMANN_DEFINE_TYPE_INTRUSIVE .","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE(type, member...)"},{"location":"features/macros/#nlohmann_define_type_intrusive_with_defaulttype-member","text":"This macro is similar to NLOHMANN_DEFINE_TYPE_INTRUSIVE . It will not throw an exception in from_json() due to a missing value in the JSON object, but can throw due to a mismatched type. The from_json() function default constructs an object and uses its values as the defaults when calling the value function. See full documentation of NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT .","title":"NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(type, member...)"},{"location":"features/macros/#nlohmann_define_type_non_intrusivetype-member","text":"This macro can be used to simplify the serialization/deserialization of types if (1) want to use a JSON object as serialization and (2) want to use the member variable names as object keys in that object. The macro is to be defined inside the namespace of the class/struct to create code for. Private members cannot be accessed. Use NLOHMANN_DEFINE_TYPE_INTRUSIVE in these scenarios. The first parameter is the name of the class/struct, and all remaining parameters name the members. See full documentation of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE .","title":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(type, member...)"},{"location":"features/macros/#nlohmann_define_type_non_intrusive_with_defaulttype-member","text":"This macro is similar to NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE . It will not throw an exception in from_json() due to a missing value in the JSON object, but can throw due to a mismatched type. The from_json() function default constructs an object and uses its values as the defaults when calling the value function. See full documentation of NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT .","title":"NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(type, member...)"},{"location":"features/macros/#nlohmann_json_serialize_enumtype","text":"This macro simplifies the serialization/deserialization of enum types. See Specializing enum conversion for more information. See full documentation of NLOHMANN_JSON_SERIALIZE_ENUM .","title":"NLOHMANN_JSON_SERIALIZE_ENUM(type, ...)"},{"location":"features/macros/#nlohmann_json_version_major-nlohmann_json_version_minor-nlohmann_json_version_patch","text":"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 .","title":"NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH"},{"location":"features/merge_patch/","text":"JSON Merge Patch \u00b6 The library supports JSON Merge Patch ( RFC 7386 ) 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 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!\" }","title":"JSON Merge Patch"},{"location":"features/merge_patch/#json-merge-patch","text":"The library supports JSON Merge Patch ( RFC 7386 ) 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 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!\" }","title":"JSON Merge Patch"},{"location":"features/namespace/","text":"nlohmann Namespace \u00b6 The 3.11.0 release introduced an inline namespace 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 \u00b6 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 serveral optional ABI tags according to the value of these ABI-affecting macros, in order: JSON_DIAGNOSTICS defined non-zero appends _diag . JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 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 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 \u00b6 Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different definitions of JSON_DIAGNOSTICS . This is illustrated in the diagram below. 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 \u00b6 Neither the compiler nor the linker will issue as much as a warning when translation units \u2013 intended to be linked together and that include different versions and/or configurations of the JSON library \u2013 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 \u00b6 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 linline namespace, allowing different versions \u2013 but not configurations \u2013 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 \u00b6 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 \u00b6 Introduced inline namespace ( json_v3_11_0[_abi-tag]* ) in version 3.11.0. Changed structure of inline namespace in version 3.11.2.","title":"nlohmann Namespace"},{"location":"features/namespace/#nlohmann-namespace","text":"The 3.11.0 release introduced an inline namespace 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.","title":"nlohmann Namespace"},{"location":"features/namespace/#structure","text":"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 serveral optional ABI tags according to the value of these ABI-affecting macros, in order: JSON_DIAGNOSTICS defined non-zero appends _diag . JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 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 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","title":"Structure"},{"location":"features/namespace/#purpose","text":"Several incompatibilities have been observed. Amongst the most common ones is linking code compiled with different definitions of JSON_DIAGNOSTICS . This is illustrated in the diagram below. 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.","title":"Purpose"},{"location":"features/namespace/#limitations","text":"Neither the compiler nor the linker will issue as much as a warning when translation units \u2013 intended to be linked together and that include different versions and/or configurations of the JSON library \u2013 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.","title":"Limitations"},{"location":"features/namespace/#disabling-the-version-component","text":"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 linline namespace, allowing different versions \u2013 but not configurations \u2013 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!","title":"Disabling the version component"},{"location":"features/namespace/#disabling-the-inline-namespace-completely","text":"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!","title":"Disabling the inline namespace completely"},{"location":"features/namespace/#version-history","text":"Introduced inline namespace ( json_v3_11_0[_abi-tag]* ) in version 3.11.0. Changed structure of inline namespace in version 3.11.2.","title":"Version history"},{"location":"features/object_order/","text":"Object Order \u00b6 The JSON standard 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 \u00b6 The default type nlohmann::json uses a std::map to store JSON objects, and thus stores object keys sorted alphabetically . Example #include #include \"json.hpp\" 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 \u00b6 If you do want to preserve the insertion order , you can try the type nlohmann::ordered_json . 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 ( integration ) or nlohmann::fifo_map ( integration ). Notes on parsing \u00b6 Note that you also need to call the right parse 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 , }","title":"Object Order"},{"location":"features/object_order/#object-order","text":"The JSON standard 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.","title":"Object Order"},{"location":"features/object_order/#default-behavior-sort-keys","text":"The default type nlohmann::json uses a std::map to store JSON objects, and thus stores object keys sorted alphabetically . Example #include #include \"json.hpp\" 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 }","title":"Default behavior: sort keys"},{"location":"features/object_order/#alternative-behavior-preserve-insertion-order","text":"If you do want to preserve the insertion order , you can try the type nlohmann::ordered_json . 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 ( integration ) or nlohmann::fifo_map ( integration ).","title":"Alternative behavior: preserve insertion order"},{"location":"features/object_order/#notes-on-parsing","text":"Note that you also need to call the right parse 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 , }","title":"Notes on parsing"},{"location":"features/binary_formats/","text":"Binary Formats \u00b6 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 (Binary JData), BSON (Binary JSON), CBOR (Concise Binary Object Representation), MessagePack , and UBJSON (Universal Binary JSON) to efficiently encode JSON values to byte vectors and to decode such vectors. Comparison \u00b6 Completeness \u00b6 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 \u00b6 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 \u00b6 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+tyoe) 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.","title":"Binary Formats"},{"location":"features/binary_formats/#binary-formats","text":"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 (Binary JData), BSON (Binary JSON), CBOR (Concise Binary Object Representation), MessagePack , and UBJSON (Universal Binary JSON) to efficiently encode JSON values to byte vectors and to decode such vectors.","title":"Binary Formats"},{"location":"features/binary_formats/#comparison","text":"","title":"Comparison"},{"location":"features/binary_formats/#completeness","text":"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","title":"Completeness"},{"location":"features/binary_formats/#binary-values","text":"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.","title":"Binary values"},{"location":"features/binary_formats/#sizes","text":"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+tyoe) 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.","title":"Sizes"},{"location":"features/binary_formats/bjdata/","text":"BJData \u00b6 The BJData format was derived from and improved upon Universal Binary JSON(UBJSON) specification (Draft 12). Specifically, it introduces an optimized array container for efficient storage of N-dimensional packed arrays ( ND-arrays ); it also adds 4 new type markers - [u] - uint16 , [m] - uint32 , [M] - uint64 and [h] - float16 - 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 are not only compact in size, fast to read/write, but also can be directly searched or read using simple processing. References BJData Specification Serialization \u00b6 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 { 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 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 : 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) ), when parsed using from_bjdata . 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 serialzed using to_bjdata , 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 UiuImlMLhdDC . 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 If the JSON data contains the binary type, the value stored is 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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_bjdata ( array ); // serialize it to BJData using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_bjdata ( array , true ); // serialize it to BJData using type optimization std :: vector < std :: uint8_t > 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 \u00b6 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 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) { 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 < std :: uint8_t > 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 }","title":"BJData"},{"location":"features/binary_formats/bjdata/#bjdata","text":"The BJData format was derived from and improved upon Universal Binary JSON(UBJSON) specification (Draft 12). Specifically, it introduces an optimized array container for efficient storage of N-dimensional packed arrays ( ND-arrays ); it also adds 4 new type markers - [u] - uint16 , [m] - uint32 , [M] - uint64 and [h] - float16 - 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 are not only compact in size, fast to read/write, but also can be directly searched or read using simple processing. References BJData Specification","title":"BJData"},{"location":"features/binary_formats/bjdata/#serialization","text":"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 { 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 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 : 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) ), when parsed using from_bjdata . 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 serialzed using to_bjdata , 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 UiuImlMLhdDC . 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 If the JSON data contains the binary type, the value stored is 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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_bjdata ( array ); // serialize it to BJData using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_bjdata ( array , true ); // serialize it to BJData using type optimization std :: vector < std :: uint8_t > 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","title":"Serialization"},{"location":"features/binary_formats/bjdata/#deserialization","text":"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 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) { 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 < std :: uint8_t > 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 }","title":"Deserialization"},{"location":"features/binary_formats/bson/","text":"BSON \u00b6 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 - the main source on BSON BSON Specification - the specification Serialization \u00b6 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 -- -- 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, integers larger than 9223372036854775807 cannot be serialized to BSON, and the 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 < std :: uint8_t > 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 \u00b6 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 0x0F unsupported int32 0x10 number_integer Timestamp 0x11 unsupported 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. Example #include #include #include using json = nlohmann :: json ; int main () { // create byte vector std :: vector < std :: uint8_t > 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 }","title":"BSON"},{"location":"features/binary_formats/bson/#bson","text":"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 - the main source on BSON BSON Specification - the specification","title":"BSON"},{"location":"features/binary_formats/bson/#serialization","text":"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 -- -- 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, integers larger than 9223372036854775807 cannot be serialized to BSON, and the 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 < std :: uint8_t > 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","title":"Serialization"},{"location":"features/binary_formats/bson/#deserialization","text":"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 0x0F unsupported int32 0x10 number_integer Timestamp 0x11 unsupported 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. Example #include #include #include using json = nlohmann :: json ; int main () { // create byte vector std :: vector < std :: uint8_t > 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 }","title":"Deserialization"},{"location":"features/binary_formats/cbor/","text":"CBOR \u00b6 The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. References CBOR Website - the main source on CBOR CBOR Playground - an interactive webpage to translate between JSON and CBOR RFC 7049 - the CBOR specification Serialization \u00b6 The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification ( RFC 7049 ): 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 : 23..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 : 23..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 : 23..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 : 23..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 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 < std :: uint8_t > 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 \u00b6 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 < std :: uint8_t > 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 }","title":"CBOR"},{"location":"features/binary_formats/cbor/#cbor","text":"The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. References CBOR Website - the main source on CBOR CBOR Playground - an interactive webpage to translate between JSON and CBOR RFC 7049 - the CBOR specification","title":"CBOR"},{"location":"features/binary_formats/cbor/#serialization","text":"The library uses the following mapping from JSON values types to CBOR types according to the CBOR specification ( RFC 7049 ): 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 : 23..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 : 23..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 : 23..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 : 23..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 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 < std :: uint8_t > 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","title":"Serialization"},{"location":"features/binary_formats/cbor/#deserialization","text":"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 < std :: uint8_t > 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 }","title":"Deserialization"},{"location":"features/binary_formats/messagepack/","text":"MessagePack \u00b6 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 MessagePack specification Serialization \u00b6 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 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 < std :: uint8_t > 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 \u00b6 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 < std :: uint8_t > 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 }","title":"MessagePack"},{"location":"features/binary_formats/messagepack/#messagepack","text":"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 MessagePack specification","title":"MessagePack"},{"location":"features/binary_formats/messagepack/#serialization","text":"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 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 < std :: uint8_t > 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","title":"Serialization"},{"location":"features/binary_formats/messagepack/#deserialization","text":"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 < std :: uint8_t > 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 }","title":"Deserialization"},{"location":"features/binary_formats/ubjson/","text":"UBJSON \u00b6 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 Serialization \u00b6 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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_ubjson ( array ); // serialize it to UBJSON using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_ubjson ( array , true ); // serialize it to UBJSON using type optimization std :: vector < std :: uint8_t > 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 \u00b6 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 < std :: uint8_t > 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 }","title":"UBJSON"},{"location":"features/binary_formats/ubjson/#ubjson","text":"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","title":"UBJSON"},{"location":"features/binary_formats/ubjson/#serialization","text":"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 < std :: uint8_t > 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 < std :: uint8_t > v_array = json :: to_ubjson ( array ); // serialize it to UBJSON using size optimization std :: vector < std :: uint8_t > v_array_size = json :: to_ubjson ( array , true ); // serialize it to UBJSON using type optimization std :: vector < std :: uint8_t > 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","title":"Serialization"},{"location":"features/binary_formats/ubjson/#deserialization","text":"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 < std :: uint8_t > 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 }","title":"Deserialization"},{"location":"features/element_access/","text":"Element Access \u00b6 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","title":"Element Access"},{"location":"features/element_access/#element-access","text":"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","title":"Element Access"},{"location":"features/element_access/checked_access/","text":"Checked access: at \u00b6 Overview \u00b6 The at 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 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 modified by 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 you 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 \u00b6 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 \u00b6 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","title":"Checked access: at"},{"location":"features/element_access/checked_access/#checked-access-at","text":"","title":"Checked access: at"},{"location":"features/element_access/checked_access/#overview","text":"The at 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 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 modified by 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 you 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","title":"Overview"},{"location":"features/element_access/checked_access/#notes","text":"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.","title":"Notes"},{"location":"features/element_access/checked_access/#summary","text":"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","title":"Summary"},{"location":"features/element_access/default_value/","text":"Access with default value: value \u00b6 Overview \u00b6 In many situations such as configuration files, missing values are not exceptional, but may be treated as if a default value was present. 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\" Note \u00b6 Exceptions value can only be used with objects. For other types, a basic_json::type_error is thrown.","title":"Access with default value: value"},{"location":"features/element_access/default_value/#access-with-default-value-value","text":"","title":"Access with default value: value"},{"location":"features/element_access/default_value/#overview","text":"In many situations such as configuration files, missing values are not exceptional, but may be treated as if a default value was present. 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\"","title":"Overview"},{"location":"features/element_access/default_value/#note","text":"Exceptions value can only be used with objects. For other types, a basic_json::type_error is thrown.","title":"Note"},{"location":"features/element_access/unchecked_access/","text":"Unchecked access: operator[] \u00b6 Overview \u00b6 Elements in a JSON object and a JSON array can be accessed via operator[] 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 be 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 \u00b6 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 \u00b6 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","title":"Unchecked access: operator[]"},{"location":"features/element_access/unchecked_access/#unchecked-access-operator","text":"","title":"Unchecked access: operator[]"},{"location":"features/element_access/unchecked_access/#overview","text":"Elements in a JSON object and a JSON array can be accessed via operator[] 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 be 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\" ] }","title":"Overview"},{"location":"features/element_access/unchecked_access/#notes","text":"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.","title":"Notes"},{"location":"features/element_access/unchecked_access/#summary","text":"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","title":"Summary"},{"location":"features/parsing/","text":"Parsing \u00b6 Note This page is under construction. Input \u00b6 SAX vs. DOM parsing \u00b6 Exceptions \u00b6 See parsing and exceptions .","title":"Parsing"},{"location":"features/parsing/#parsing","text":"Note This page is under construction.","title":"Parsing"},{"location":"features/parsing/#input","text":"","title":"Input"},{"location":"features/parsing/#sax-vs-dom-parsing","text":"","title":"SAX vs. DOM parsing"},{"location":"features/parsing/#exceptions","text":"See parsing and exceptions .","title":"Exceptions"},{"location":"features/parsing/json_lines/","text":"JSON Lines \u00b6 The JSON Lines format is a text format of newline-delimited JSON. In particular: The input must be UTF-8 encoded. Every line must be a valid JSON value. The line separator must be \\n . As \\r is silently ignored, \\r\\n is also supported. The final character may be \\n , but is not required to be one. JSON Text example { \"name\" : \"Gilbert\" , \"wins\" : [[ \"straight\" , \"7\u2663\" ], [ \"one pair\" , \"10\u2665\" ]]} { \"name\" : \"Alexa\" , \"wins\" : [[ \"two pair\" , \"4\u2660\" ], [ \"two pair\" , \"9\u2660\" ]]} { \"name\" : \"May\" , \"wins\" : []} { \"name\" : \"Deloise\" , \"wins\" : [[ \"three of a kind\" , \"5\u2663\" ]]} JSON Lines input with more than one value is treated as invalid JSON by the parse or accept functions. To process it line by line, functions like std::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\u2663\"], [\"one pair\", \"10\u2665\"]]} {\"name\": \"Alexa\", \"wins\": [[\"two pair\", \"4\u2660\"], [\"two pair\", \"9\u2660\"]]} {\"name\": \"May\", \"wins\": []} {\"name\": \"Deloise\", \"wins\": [[\"three of a kind\", \"5\u2663\"]]} ) \" ; std :: string line ; while ( std :: getline ( input , line )) { std :: cout << json :: parse ( line ) << std :: endl ; } } Output: { \"name\" : \"Gilbert\" , \"wins\" :[[ \"straight\" , \"7\u2663\" ],[ \"one pair\" , \"10\u2665\" ]]} { \"name\" : \"Alexa\" , \"wins\" :[[ \"two pair\" , \"4\u2660\" ],[ \"two pair\" , \"9\u2660\" ]]} { \"name\" : \"May\" , \"wins\" :[]} { \"name\" : \"Deloise\" , \"wins\" :[[ \"three of a kind\" , \"5\u2663\" ]]} Note Using operator>> 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.","title":"JSON Lines"},{"location":"features/parsing/json_lines/#json-lines","text":"The JSON Lines format is a text format of newline-delimited JSON. In particular: The input must be UTF-8 encoded. Every line must be a valid JSON value. The line separator must be \\n . As \\r is silently ignored, \\r\\n is also supported. The final character may be \\n , but is not required to be one. JSON Text example { \"name\" : \"Gilbert\" , \"wins\" : [[ \"straight\" , \"7\u2663\" ], [ \"one pair\" , \"10\u2665\" ]]} { \"name\" : \"Alexa\" , \"wins\" : [[ \"two pair\" , \"4\u2660\" ], [ \"two pair\" , \"9\u2660\" ]]} { \"name\" : \"May\" , \"wins\" : []} { \"name\" : \"Deloise\" , \"wins\" : [[ \"three of a kind\" , \"5\u2663\" ]]} JSON Lines input with more than one value is treated as invalid JSON by the parse or accept functions. To process it line by line, functions like std::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\u2663\"], [\"one pair\", \"10\u2665\"]]} {\"name\": \"Alexa\", \"wins\": [[\"two pair\", \"4\u2660\"], [\"two pair\", \"9\u2660\"]]} {\"name\": \"May\", \"wins\": []} {\"name\": \"Deloise\", \"wins\": [[\"three of a kind\", \"5\u2663\"]]} ) \" ; std :: string line ; while ( std :: getline ( input , line )) { std :: cout << json :: parse ( line ) << std :: endl ; } } Output: { \"name\" : \"Gilbert\" , \"wins\" :[[ \"straight\" , \"7\u2663\" ],[ \"one pair\" , \"10\u2665\" ]]} { \"name\" : \"Alexa\" , \"wins\" :[[ \"two pair\" , \"4\u2660\" ],[ \"two pair\" , \"9\u2660\" ]]} { \"name\" : \"May\" , \"wins\" :[]} { \"name\" : \"Deloise\" , \"wins\" :[[ \"three of a kind\" , \"5\u2663\" ]]} Note Using operator>> 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.","title":"JSON Lines"},{"location":"features/parsing/parse_exceptions/","text":"Parsing and Exceptions \u00b6 When the input is not valid JSON, an exception of type parse_error 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 . 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 \u00b6 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 \u00b6 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 \u00b6 Finally, you can implement the SAX interface 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 \"json.hpp\" using json = nlohmann :: json ; class sax_no_exception : public nlohmann :: detail :: json_sax_dom_parser < json > { public : sax_no_exception ( json & j ) : nlohmann :: detail :: json_sax_dom_parser < json > ( 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]","title":"Parsing and Exceptions"},{"location":"features/parsing/parse_exceptions/#parsing-and-exceptions","text":"When the input is not valid JSON, an exception of type parse_error 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 . 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:","title":"Parsing and Exceptions"},{"location":"features/parsing/parse_exceptions/#switch-off-exceptions","text":"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.","title":"Switch off exceptions"},{"location":"features/parsing/parse_exceptions/#use-accept-function","text":"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.","title":"Use accept() function"},{"location":"features/parsing/parse_exceptions/#user-defined-sax-interface","text":"Finally, you can implement the SAX interface 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 \"json.hpp\" using json = nlohmann :: json ; class sax_no_exception : public nlohmann :: detail :: json_sax_dom_parser < json > { public : sax_no_exception ( json & j ) : nlohmann :: detail :: json_sax_dom_parser < json > ( 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]","title":"User-defined SAX interface"},{"location":"features/parsing/parser_callbacks/","text":"Parser Callbacks \u00b6 Overview \u00b6 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 < typename BasicJsonType > using parser_callback_t = std :: function < bool ( int depth , parse_event_t event , BasicJsonType & parsed ) > ; Callback event types \u00b6 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 \u00b6 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 } }","title":"Parser Callbacks"},{"location":"features/parsing/parser_callbacks/#parser-callbacks","text":"","title":"Parser Callbacks"},{"location":"features/parsing/parser_callbacks/#overview","text":"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 < typename BasicJsonType > using parser_callback_t = std :: function < bool ( int depth , parse_event_t event , BasicJsonType & parsed ) > ;","title":"Overview"},{"location":"features/parsing/parser_callbacks/#callback-event-types","text":"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\" }","title":"Callback event types"},{"location":"features/parsing/parser_callbacks/#return-value","text":"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 } }","title":"Return value"},{"location":"features/parsing/sax_interface/","text":"SAX Interface \u00b6 The library uses a SAX-like interface with the following functions: // 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 & 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: 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. Create an object of your SAX interface class, e.g. my_sax . 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 \u00b6 json_sax - documentation of the SAX interface sax_parse - SAX parser","title":"SAX Interface"},{"location":"features/parsing/sax_interface/#sax-interface","text":"The library uses a SAX-like interface with the following functions: // 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 & 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: 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. Create an object of your SAX interface class, e.g. my_sax . 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 .","title":"SAX Interface"},{"location":"features/parsing/sax_interface/#see-also","text":"json_sax - documentation of the SAX interface sax_parse - SAX parser","title":"See also"},{"location":"features/types/","text":"Types \u00b6 This page gives an overview how JSON values are stored and how this can be configured. Overview \u00b6 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 \u00b6 Template arguments \u00b6 The data types to store a JSON value are derived from the template arguments passed to class basic_json : template < template < typename U , typename V , typename ... Args > class ObjectType = std :: map , template < typename U , typename ... Args > 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 < typename U > class AllocatorType = std :: allocator , template < typename T , typename SFINAE = void > class JSONSerializer = adl_serializer , class BinaryType = std :: vector < std :: uint8_t > > 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 < StringType , basic_json , object_comparator_t , AllocatorType < std :: pair < const StringType , basic_json >>> ; using array_t = ArrayType < basic_json , AllocatorType < basic_json >> ; 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 < BinaryType > ; Objects \u00b6 RFC 8259 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 \u00b6 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 < std :: pair < const std :: string , basic_json >> // allocator_type > Behavior \u00b6 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 \u00b6 The order 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 , because any order implements the specified \"unordered\" nature of JSON objects. Limits \u00b6 RFC 8259 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 \u00b6 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 \u00b6 RFC 8259 describes JSON arrays as follows: An array is an ordered sequence of zero or more values. Default type \u00b6 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 < basic_json > // allocator_type > Limits \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 With the default values for StringType ( std::string ), the default value for string_t is std :: string . Encoding \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false . Default type \u00b6 With the default values for BooleanType ( bool ), the default value for boolean_t is bool . Storage \u00b6 Boolean values are stored directly inside a basic_json type. Numbers \u00b6 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 \u00b6 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 \u00b6 The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 \u00b6 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 be 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 be 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] [-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 \u00b6 Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a basic_json type.","title":"Types"},{"location":"features/types/#types","text":"This page gives an overview how JSON values are stored and how this can be configured.","title":"Types"},{"location":"features/types/#overview","text":"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.","title":"Overview"},{"location":"features/types/#storage","text":"","title":"Storage"},{"location":"features/types/#template-arguments","text":"The data types to store a JSON value are derived from the template arguments passed to class basic_json : template < template < typename U , typename V , typename ... Args > class ObjectType = std :: map , template < typename U , typename ... Args > 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 < typename U > class AllocatorType = std :: allocator , template < typename T , typename SFINAE = void > class JSONSerializer = adl_serializer , class BinaryType = std :: vector < std :: uint8_t > > 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 < StringType , basic_json , object_comparator_t , AllocatorType < std :: pair < const StringType , basic_json >>> ; using array_t = ArrayType < basic_json , AllocatorType < basic_json >> ; 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 < BinaryType > ;","title":"Template arguments"},{"location":"features/types/#objects","text":"RFC 8259 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.","title":"Objects"},{"location":"features/types/#default-type","text":"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 < std :: pair < const std :: string , basic_json >> // allocator_type >","title":"Default type"},{"location":"features/types/#behavior","text":"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.","title":"Behavior"},{"location":"features/types/#key-order","text":"The order 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 , because any order implements the specified \"unordered\" nature of JSON objects.","title":"Key order"},{"location":"features/types/#limits","text":"RFC 8259 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.","title":"Limits"},{"location":"features/types/#storage_1","text":"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.","title":"Storage"},{"location":"features/types/#arrays","text":"RFC 8259 describes JSON arrays as follows: An array is an ordered sequence of zero or more values.","title":"Arrays"},{"location":"features/types/#default-type_1","text":"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 < basic_json > // allocator_type >","title":"Default type"},{"location":"features/types/#limits_1","text":"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.","title":"Limits"},{"location":"features/types/#storage_2","text":"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.","title":"Storage"},{"location":"features/types/#strings","text":"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.","title":"Strings"},{"location":"features/types/#default-type_2","text":"With the default values for StringType ( std::string ), the default value for string_t is std :: string .","title":"Default type"},{"location":"features/types/#encoding","text":"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.","title":"Encoding"},{"location":"features/types/#string-comparison","text":"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.","title":"String comparison"},{"location":"features/types/#storage_3","text":"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.","title":"Storage"},{"location":"features/types/#booleans","text":"RFC 8259 implicitly describes a boolean as a type which differentiates the two literals true and false .","title":"Booleans"},{"location":"features/types/#default-type_3","text":"With the default values for BooleanType ( bool ), the default value for boolean_t is bool .","title":"Default type"},{"location":"features/types/#storage_4","text":"Boolean values are stored directly inside a basic_json type.","title":"Storage"},{"location":"features/types/#numbers","text":"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.","title":"Numbers"},{"location":"features/types/#default-types","text":"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 .","title":"Default types"},{"location":"features/types/#default-behavior","text":"The restrictions about leading zeros is not enforced in C++. Instead, leading zeros in integer literals lead to an interpretation as octal number. Internally, the value will be stored as 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 .","title":"Default behavior"},{"location":"features/types/#limits_2","text":"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 be 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 be 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] [-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 .","title":"Limits"},{"location":"features/types/#storage_5","text":"Integer number values, unsigned integer number values, and floating-point number values are stored directly inside a basic_json type.","title":"Storage"},{"location":"features/types/number_handling/","text":"Number Handling \u00b6 This document describes how the library is handling numbers. Background \u00b6 This section briefly summarizes how the JSON specification describes how numbers should be handled. JSON number syntax \u00b6 JSON defines the syntax of numbers as follows: RFC 8259 , 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 visualizes the number syntax: Number interoperability \u00b6 On number interoperability, the following remarks are made: RFC 8259 , 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] [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values. Library implementation \u00b6 This section describes how the above number specification is implemented by this library. Number storage \u00b6 In the default json 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 . As of version 3.9.1, the conversion is realized by std::strtoull , std::strtoll , and std::strtod , 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 \u00b6 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 are not satisfying std::isfinite such as 1E400 ) will throw exception json.exception.out_of_range.406 during parsing. Floating-point numbers are rounded to the next number representable as double . For instance 3.141592653589793238462643383279 is stored as 0x400921fb54442d18 . This is the same behavior as the code double x = 3.141592653589793238462643383279 ; . Interoperability The library interoperable with respect to the specification, because its supported range [-2^{63}, 2^{64}-1] [-2^{63}, 2^{64}-1] is larger than the described range [-2^{53}+1, 2^{53}-1] [-2^{53}+1, 2^{53}-1] . All integers outside the range [-2^{63}, 2^{64}-1] [-2^{63}, 2^{64}-1] , as well as floating-point numbers are stored as double . This also concurs with the specification above. Zeros \u00b6 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 \u00b6 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 significant digits. The rationale is to use the shortest representation while still allow 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 < double >:: max_digits10 , double_value ); NaN handling \u00b6 NaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded: RFC 8259 , 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, NaN values can be stored in a JSON value by assignment. This library serializes NaN values as null . This corresponds to the behavior of JavaScript's JSON.stringify function. Example The following example shows how a NaN value is stored in a json value. int main () { double val = std :: numeric_limits < double >:: 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 \u00b6 Floating-point inside JSON values numbers 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 could be used, for instance template < typename T , typename = typename std :: enable_if < std :: is_floating_point < T >:: value , T >:: type > inline bool is_same ( T a , T b , T epsilon = std :: numeric_limits < T >:: 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 < float >:: epsilon (); // other cases remain the same with the original ... } } ... } (see #703 for more information.) Note NaN values never compare equal to themselves or to other NaN values. See #514 . Number conversion \u00b6 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 to integers. 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 < std :: int64_t > (); // now i==42; no warning or error is produced Note the last line with throw a json.exception.type_error.302 exception if jd is not a numerical type, for instance a string. The rationale is twofold: JSON does not define a number type or precision (see #json-specification ). C++ also allows to silently convert 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() or is_number_unsigned() : // 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 < std :: int64_t > (); // ... } 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 .) Determine number types \u00b6 As the example in Number conversion shows, there are different functions to determine the type of the stored number: is_number() returns true for any number type is_number_integer() returns true for signed and unsigned integers is_number_unsigned() returns true for unsigned integers only is_number_float() returns true for floating-point numbers type_name() returns \"number\" for any number type type() returns a different enumerator of value_t for all number types 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 \u00b6 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 .","title":"Number Handling"},{"location":"features/types/number_handling/#number-handling","text":"This document describes how the library is handling numbers.","title":"Number Handling"},{"location":"features/types/number_handling/#background","text":"This section briefly summarizes how the JSON specification describes how numbers should be handled.","title":"Background"},{"location":"features/types/number_handling/#json-number-syntax","text":"JSON defines the syntax of numbers as follows: RFC 8259 , 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 visualizes the number syntax:","title":"JSON number syntax"},{"location":"features/types/number_handling/#number-interoperability","text":"On number interoperability, the following remarks are made: RFC 8259 , 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] [-2^{53}+1, 2^{53}-1] are interoperable in the sense that implementations will agree exactly on their numeric values.","title":"Number interoperability"},{"location":"features/types/number_handling/#library-implementation","text":"This section describes how the above number specification is implemented by this library.","title":"Library implementation"},{"location":"features/types/number_handling/#number-storage","text":"In the default json 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 . As of version 3.9.1, the conversion is realized by std::strtoull , std::strtoll , and std::strtod , 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 .","title":"Number storage"},{"location":"features/types/number_handling/#number-limits","text":"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 are not satisfying std::isfinite such as 1E400 ) will throw exception json.exception.out_of_range.406 during parsing. Floating-point numbers are rounded to the next number representable as double . For instance 3.141592653589793238462643383279 is stored as 0x400921fb54442d18 . This is the same behavior as the code double x = 3.141592653589793238462643383279 ; . Interoperability The library interoperable with respect to the specification, because its supported range [-2^{63}, 2^{64}-1] [-2^{63}, 2^{64}-1] is larger than the described range [-2^{53}+1, 2^{53}-1] [-2^{53}+1, 2^{53}-1] . All integers outside the range [-2^{63}, 2^{64}-1] [-2^{63}, 2^{64}-1] , as well as floating-point numbers are stored as double . This also concurs with the specification above.","title":"Number limits"},{"location":"features/types/number_handling/#zeros","text":"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 - .","title":"Zeros"},{"location":"features/types/number_handling/#number-serialization","text":"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 significant digits. The rationale is to use the shortest representation while still allow 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 < double >:: max_digits10 , double_value );","title":"Number serialization"},{"location":"features/types/number_handling/#nan-handling","text":"NaN (not-a-number) cannot be expressed with the number syntax described above and are in fact explicitly excluded: RFC 8259 , 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, NaN values can be stored in a JSON value by assignment. This library serializes NaN values as null . This corresponds to the behavior of JavaScript's JSON.stringify function. Example The following example shows how a NaN value is stored in a json value. int main () { double val = std :: numeric_limits < double >:: 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","title":"NaN handling"},{"location":"features/types/number_handling/#number-comparison","text":"Floating-point inside JSON values numbers 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 could be used, for instance template < typename T , typename = typename std :: enable_if < std :: is_floating_point < T >:: value , T >:: type > inline bool is_same ( T a , T b , T epsilon = std :: numeric_limits < T >:: 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 < float >:: epsilon (); // other cases remain the same with the original ... } } ... } (see #703 for more information.) Note NaN values never compare equal to themselves or to other NaN values. See #514 .","title":"Number comparison"},{"location":"features/types/number_handling/#number-conversion","text":"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 to integers. 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 < std :: int64_t > (); // now i==42; no warning or error is produced Note the last line with throw a json.exception.type_error.302 exception if jd is not a numerical type, for instance a string. The rationale is twofold: JSON does not define a number type or precision (see #json-specification ). C++ also allows to silently convert 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() or is_number_unsigned() : // 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 < std :: int64_t > (); // ... } 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 .)","title":"Number conversion"},{"location":"features/types/number_handling/#determine-number-types","text":"As the example in Number conversion shows, there are different functions to determine the type of the stored number: is_number() returns true for any number type is_number_integer() returns true for signed and unsigned integers is_number_unsigned() returns true for unsigned integers only is_number_float() returns true for floating-point numbers type_name() returns \"number\" for any number type type() returns a different enumerator of value_t for all number types 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","title":"Determine number types"},{"location":"features/types/number_handling/#template-number-types","text":"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 .","title":"Template number types"},{"location":"home/code_of_conduct/","text":"Contributor Covenant Code of Conduct \u00b6 Our Pledge \u00b6 In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. Our Standards \u00b6 Examples of behavior that contributes to creating a positive environment include: Using welcoming and inclusive language Being respectful of differing viewpoints and experiences Gracefully accepting constructive criticism Focusing on what is best for the community Showing empathy towards other community members Examples of unacceptable behavior by participants include: The use of sexualized language or imagery and unwelcome sexual attention or advances Trolling, insulting/derogatory comments, and personal or political attacks Public or private harassment Publishing others' private information, such as a physical or electronic address, without explicit permission Other conduct which could reasonably be considered inappropriate in a professional setting Our Responsibilities \u00b6 Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers 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, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. Scope \u00b6 This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. Enforcement \u00b6 Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. Attribution \u00b6 This Code of Conduct is adapted from the Contributor Covenant , version 1.4, available at http://contributor-covenant.org/version/1/4","title":"Code of Conduct"},{"location":"home/code_of_conduct/#contributor-covenant-code-of-conduct","text":"","title":"Contributor Covenant Code of Conduct"},{"location":"home/code_of_conduct/#our-pledge","text":"In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.","title":"Our Pledge"},{"location":"home/code_of_conduct/#our-standards","text":"Examples of behavior that contributes to creating a positive environment include: Using welcoming and inclusive language Being respectful of differing viewpoints and experiences Gracefully accepting constructive criticism Focusing on what is best for the community Showing empathy towards other community members Examples of unacceptable behavior by participants include: The use of sexualized language or imagery and unwelcome sexual attention or advances Trolling, insulting/derogatory comments, and personal or political attacks Public or private harassment Publishing others' private information, such as a physical or electronic address, without explicit permission Other conduct which could reasonably be considered inappropriate in a professional setting","title":"Our Standards"},{"location":"home/code_of_conduct/#our-responsibilities","text":"Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers 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, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.","title":"Our Responsibilities"},{"location":"home/code_of_conduct/#scope","text":"This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.","title":"Scope"},{"location":"home/code_of_conduct/#enforcement","text":"Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mail@nlohmann.me . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.","title":"Enforcement"},{"location":"home/code_of_conduct/#attribution","text":"This Code of Conduct is adapted from the Contributor Covenant , version 1.4, available at http://contributor-covenant.org/version/1/4","title":"Attribution"},{"location":"home/design_goals/","text":"Design goals \u00b6 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. Check out the examples below , and you'll know what I mean. 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.","title":"Design goals"},{"location":"home/design_goals/#design-goals","text":"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. Check out the examples below , and you'll know what I mean. 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.","title":"Design goals"},{"location":"home/exceptions/","text":"Exceptions \u00b6 Overview \u00b6 Base type \u00b6 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. Switch off exceptions \u00b6 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 . 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 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() string of exceptions is not available for MSVC if exceptions are disabled, see #2824 . See documentation of JSON_TRY_USER , JSON_CATCH_USER and JSON_THROW_USER for more information. Extended diagnostic messages \u00b6 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 ( 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 lead to the exception) can be created. That global context is provided as JSON Pointer . 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 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 ( 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 for more information. Parse errors \u00b6 This exception is thrown by the library 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 ( 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 \u00b6 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: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal 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 http://jsonlint.com or a tool like jq . json.exception.parse_error.102 \u00b6 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 with a more detailed description is used. json.exception.parse_error.103 \u00b6 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 with a more detailed description is used. json.exception.parse_error.104 \u00b6 RFC 6902 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 \u00b6 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 \u00b6 An array index in a JSON Pointer ( RFC 6901 ) 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 An unexpected byte was read in a binary format or length information is invalid ( BSON ). 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 ( 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 \u00b6 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 \u00b6 In the erase 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 \u00b6 Either iterator passed to function erase(IteratorType first, IteratorType last ) 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 \u00b6 When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase 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 \u00b6 When an iterator for a primitive type (number, boolean, or string) is passed to an erase 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 The iterator range passed to the insert function 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.210] iterators do not fit json.exception.invalid_iterator.211 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to begin() . Example message [json.exception.invalid_iterator.214] cannot get value Type errors \u00b6 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 ( 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 \u00b6 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 \u00b6 During implicit or explicit value conversion, the JSON type must be compatible to 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 The erase() 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 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 \u00b6 This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance in 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 ( 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 \u00b6 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 \u00b6 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 \u00b6 The provided key was not found in the JSON object. Example message key 'foo' not found json.exception.out_of_range.404 \u00b6 A reference token in a JSON Pointer could not be resolved. Example message unresolved reference token 'foo' json.exception.out_of_range.405 \u00b6 The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. Example message JSON pointer has no parent json.exception.out_of_range.406 \u00b6 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 \u00b6 UBJSON and BSON only support integer numbers up to 9223372036854775807. Example message number overflow serializing '9223372036854775808' Note Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers, and this exception does not further occur. json.exception.out_of_range.408 \u00b6 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 \u00b6 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) Further exceptions \u00b6 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 ( 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 \u00b6 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\"}","title":"Exceptions"},{"location":"home/exceptions/#exceptions","text":"","title":"Exceptions"},{"location":"home/exceptions/#overview","text":"","title":"Overview"},{"location":"home/exceptions/#base-type","text":"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.","title":"Base type"},{"location":"home/exceptions/#switch-off-exceptions","text":"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 . 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 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() string of exceptions is not available for MSVC if exceptions are disabled, see #2824 . See documentation of JSON_TRY_USER , JSON_CATCH_USER and JSON_THROW_USER for more information.","title":"Switch off exceptions"},{"location":"home/exceptions/#extended-diagnostic-messages","text":"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 ( 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 lead to the exception) can be created. That global context is provided as JSON Pointer . 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 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 ( 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 for more information.","title":"Extended diagnostic messages"},{"location":"home/exceptions/#parse-errors","text":"This exception is thrown by the library 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 ( 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","title":"Parse errors"},{"location":"home/exceptions/#jsonexceptionparse_error101","text":"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: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal 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 http://jsonlint.com or a tool like jq .","title":"json.exception.parse_error.101"},{"location":"home/exceptions/#jsonexceptionparse_error102","text":"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 with a more detailed description is used.","title":"json.exception.parse_error.102"},{"location":"home/exceptions/#jsonexceptionparse_error103","text":"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 with a more detailed description is used.","title":"json.exception.parse_error.103"},{"location":"home/exceptions/#jsonexceptionparse_error104","text":"RFC 6902 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","title":"json.exception.parse_error.104"},{"location":"home/exceptions/#jsonexceptionparse_error105","text":"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","title":"json.exception.parse_error.105"},{"location":"home/exceptions/#jsonexceptionparse_error106","text":"An array index in a JSON Pointer ( RFC 6901 ) 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'","title":"json.exception.parse_error.106"},{"location":"home/exceptions/#jsonexceptionparse_error107","text":"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'","title":"json.exception.parse_error.107"},{"location":"home/exceptions/#jsonexceptionparse_error108","text":"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'","title":"json.exception.parse_error.108"},{"location":"home/exceptions/#jsonexceptionparse_error109","text":"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","title":"json.exception.parse_error.109"},{"location":"home/exceptions/#jsonexceptionparse_error110","text":"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","title":"json.exception.parse_error.110"},{"location":"home/exceptions/#jsonexceptionparse_error112","text":"An unexpected byte was read in a binary format or length information is invalid ( BSON ). 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","title":"json.exception.parse_error.112"},{"location":"home/exceptions/#jsonexceptionparse_error113","text":"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","title":"json.exception.parse_error.113"},{"location":"home/exceptions/#jsonexceptionparse_error114","text":"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","title":"json.exception.parse_error.114"},{"location":"home/exceptions/#jsonexceptionparse_error115","text":"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","title":"json.exception.parse_error.115"},{"location":"home/exceptions/#iterator-errors","text":"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 ( 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","title":"Iterator errors"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator201","text":"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","title":"json.exception.invalid_iterator.201"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator202","text":"In the erase 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","title":"json.exception.invalid_iterator.202"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator203","text":"Either iterator passed to function erase(IteratorType first, IteratorType last ) 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","title":"json.exception.invalid_iterator.203"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator204","text":"When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase 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","title":"json.exception.invalid_iterator.204"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator205","text":"When an iterator for a primitive type (number, boolean, or string) is passed to an erase 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","title":"json.exception.invalid_iterator.205"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator206","text":"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","title":"json.exception.invalid_iterator.206"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator207","text":"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","title":"json.exception.invalid_iterator.207"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator208","text":"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","title":"json.exception.invalid_iterator.208"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator209","text":"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","title":"json.exception.invalid_iterator.209"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator210","text":"The iterator range passed to the insert function 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.210] iterators do not fit","title":"json.exception.invalid_iterator.210"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator211","text":"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","title":"json.exception.invalid_iterator.211"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator212","text":"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","title":"json.exception.invalid_iterator.212"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator213","text":"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","title":"json.exception.invalid_iterator.213"},{"location":"home/exceptions/#jsonexceptioninvalid_iterator214","text":"Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to begin() . Example message [json.exception.invalid_iterator.214] cannot get value","title":"json.exception.invalid_iterator.214"},{"location":"home/exceptions/#type-errors","text":"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 ( 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","title":"Type errors"},{"location":"home/exceptions/#jsonexceptiontype_error301","text":"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","title":"json.exception.type_error.301"},{"location":"home/exceptions/#jsonexceptiontype_error302","text":"During implicit or explicit value conversion, the JSON type must be compatible to 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","title":"json.exception.type_error.302"},{"location":"home/exceptions/#jsonexceptiontype_error303","text":"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\"","title":"json.exception.type_error.303"},{"location":"home/exceptions/#jsonexceptiontype_error304","text":"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","title":"json.exception.type_error.304"},{"location":"home/exceptions/#jsonexceptiontype_error305","text":"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","title":"json.exception.type_error.305"},{"location":"home/exceptions/#jsonexceptiontype_error306","text":"The value() member functions can only be executed for certain JSON types. Example message [json.exception.type_error.306] cannot use value() with number","title":"json.exception.type_error.306"},{"location":"home/exceptions/#jsonexceptiontype_error307","text":"The erase() member functions can only be executed for certain JSON types. Example message [json.exception.type_error.307] cannot use erase() with string","title":"json.exception.type_error.307"},{"location":"home/exceptions/#jsonexceptiontype_error308","text":"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","title":"json.exception.type_error.308"},{"location":"home/exceptions/#jsonexceptiontype_error309","text":"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","title":"json.exception.type_error.309"},{"location":"home/exceptions/#jsonexceptiontype_error310","text":"The swap() member functions can only be executed for certain JSON types. Example message [json.exception.type_error.310] cannot use swap() with number","title":"json.exception.type_error.310"},{"location":"home/exceptions/#jsonexceptiontype_error311","text":"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","title":"json.exception.type_error.311"},{"location":"home/exceptions/#jsonexceptiontype_error312","text":"The update() member functions can only be executed for certain JSON types. Example message [json.exception.type_error.312] cannot use update() with array","title":"json.exception.type_error.312"},{"location":"home/exceptions/#jsonexceptiontype_error313","text":"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","title":"json.exception.type_error.313"},{"location":"home/exceptions/#jsonexceptiontype_error314","text":"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","title":"json.exception.type_error.314"},{"location":"home/exceptions/#jsonexceptiontype_error315","text":"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","title":"json.exception.type_error.315"},{"location":"home/exceptions/#jsonexceptiontype_error316","text":"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","title":"json.exception.type_error.316"},{"location":"home/exceptions/#jsonexceptiontype_error317","text":"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 }","title":"json.exception.type_error.317"},{"location":"home/exceptions/#out-of-range","text":"This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance in 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 ( 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","title":"Out of range"},{"location":"home/exceptions/#jsonexceptionout_of_range401","text":"The provided array index i is larger than size-1 . Example message array index 3 is out of range","title":"json.exception.out_of_range.401"},{"location":"home/exceptions/#jsonexceptionout_of_range402","text":"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","title":"json.exception.out_of_range.402"},{"location":"home/exceptions/#jsonexceptionout_of_range403","text":"The provided key was not found in the JSON object. Example message key 'foo' not found","title":"json.exception.out_of_range.403"},{"location":"home/exceptions/#jsonexceptionout_of_range404","text":"A reference token in a JSON Pointer could not be resolved. Example message unresolved reference token 'foo'","title":"json.exception.out_of_range.404"},{"location":"home/exceptions/#jsonexceptionout_of_range405","text":"The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. Example message JSON pointer has no parent","title":"json.exception.out_of_range.405"},{"location":"home/exceptions/#jsonexceptionout_of_range406","text":"A parsed number could not be stored as without changing it to NaN or INF. Example message number overflow parsing '10E1000'","title":"json.exception.out_of_range.406"},{"location":"home/exceptions/#jsonexceptionout_of_range407","text":"UBJSON and BSON only support integer numbers up to 9223372036854775807. Example message number overflow serializing '9223372036854775808' Note Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers, and this exception does not further occur.","title":"json.exception.out_of_range.407"},{"location":"home/exceptions/#jsonexceptionout_of_range408","text":"The size (following # ) of an UBJSON array or object exceeds the maximal capacity. Example message excessive array size: 8658170730974374167","title":"json.exception.out_of_range.408"},{"location":"home/exceptions/#jsonexceptionout_of_range409","text":"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)","title":"json.exception.out_of_range.409"},{"location":"home/exceptions/#further-exceptions","text":"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 ( 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","title":"Further exceptions"},{"location":"home/exceptions/#jsonexceptionother_error501","text":"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\"}","title":"json.exception.other_error.501"},{"location":"home/faq/","text":"Frequently Asked Questions (FAQ) \u00b6 Known bugs \u00b6 Brace initialization yields arrays \u00b6 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. Limitations \u00b6 Relaxed parsing \u00b6 Question Can you add an option to ignore trailing commas? This library does not support any feature which would jeopardize interoperability. Parse errors reading non-ASCII characters \u00b6 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\u00e9$')\" 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 . 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. Unicode noncharacters will not be replaced by the library. 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() 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 \u00b6 Question Why are wide strings (e.g., std::wstring ) dumped as arrays of numbers? As described above , 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 < std :: codecvt_utf8 < wchar_t >> utf8_conv ; return utf8_conv . to_bytes ( wide_string ); } json j ; std :: wstring ws = L \"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\" ; j [ \"original\" ] = ws ; j [ \"encoded\" ] = to_utf8 ( ws ); std :: cout << j << std :: endl ; The result is: { \"encoded\" : \"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\" , \"original\" : [ 36554 , 66 , 49 , 50 , 51 , 52 , 32 , 12371 , 12435 , 12395 , 12385 , 12399 ] } Exceptions \u00b6 Parsing without exceptions \u00b6 Question Is it possible to indicate a parse error without throwing an exception? Yes, see Parsing and exceptions . Key name in exceptions \u00b6 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 \u00b6 Number precision \u00b6 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 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 on the library's number handling for more information. Compilation issues \u00b6 Android SDK \u00b6 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 \u00b6 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 .","title":"FAQ"},{"location":"home/faq/#frequently-asked-questions-faq","text":"","title":"Frequently Asked Questions (FAQ)"},{"location":"home/faq/#known-bugs","text":"","title":"Known bugs"},{"location":"home/faq/#brace-initialization-yields-arrays","text":"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.","title":"Brace initialization yields arrays"},{"location":"home/faq/#limitations","text":"","title":"Limitations"},{"location":"home/faq/#relaxed-parsing","text":"Question Can you add an option to ignore trailing commas? This library does not support any feature which would jeopardize interoperability.","title":"Relaxed parsing"},{"location":"home/faq/#parse-errors-reading-non-ascii-characters","text":"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\u00e9$')\" 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 . 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. Unicode noncharacters will not be replaced by the library. 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() 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.","title":"Parse errors reading non-ASCII characters"},{"location":"home/faq/#wide-string-handling","text":"Question Why are wide strings (e.g., std::wstring ) dumped as arrays of numbers? As described above , 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 < std :: codecvt_utf8 < wchar_t >> utf8_conv ; return utf8_conv . to_bytes ( wide_string ); } json j ; std :: wstring ws = L \"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\" ; j [ \"original\" ] = ws ; j [ \"encoded\" ] = to_utf8 ( ws ); std :: cout << j << std :: endl ; The result is: { \"encoded\" : \"\u8ecaB1234 \u3053\u3093\u306b\u3061\u306f\" , \"original\" : [ 36554 , 66 , 49 , 50 , 51 , 52 , 32 , 12371 , 12435 , 12395 , 12385 , 12399 ] }","title":"Wide string handling"},{"location":"home/faq/#exceptions","text":"","title":"Exceptions"},{"location":"home/faq/#parsing-without-exceptions","text":"Question Is it possible to indicate a parse error without throwing an exception? Yes, see Parsing and exceptions .","title":"Parsing without exceptions"},{"location":"home/faq/#key-name-in-exceptions","text":"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 .","title":"Key name in exceptions"},{"location":"home/faq/#serialization-issues","text":"","title":"Serialization issues"},{"location":"home/faq/#number-precision","text":"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 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 on the library's number handling for more information.","title":"Number precision"},{"location":"home/faq/#compilation-issues","text":"","title":"Compilation issues"},{"location":"home/faq/#android-sdk","text":"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.","title":"Android SDK"},{"location":"home/faq/#missing-stl-function","text":"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 .","title":"Missing STL function"},{"location":"home/license/","text":"License \u00b6 The class is licensed under the MIT License : Copyright \u00a9 2013-2022 Niels Lohmann Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \u201cSoftware\u201d), 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 \u201cAS IS\u201d, 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 \u00a9 2008-2009 Bj\u00f6rn 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 \u00a9 2009 Florian Loitsch The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0 .","title":"License"},{"location":"home/license/#license","text":"The class is licensed under the MIT License : Copyright \u00a9 2013-2022 Niels Lohmann Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \u201cSoftware\u201d), 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 \u201cAS IS\u201d, 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 \u00a9 2008-2009 Bj\u00f6rn 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 \u00a9 2009 Florian Loitsch The class contains a copy of Hedley from Evan Nemerson which is licensed as CC0-1.0 .","title":"License"},{"location":"home/releases/","text":"Releases \u00b6 v3.7.3 \u00b6 Files include.zip (274 KB) include.zip.asc (1 KB) json.hpp (791 KB) json.hpp.asc (1 KB) Release date: 2019-11-17 SHA-256: 3b5d2b8f8282b80557091514d8ab97e27f9574336c804ee666fda673a9b59926 (json.hpp), 87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014 (include.zip) Summary \u00b6 This release fixes a bug introduced in release 3.7.2 which could yield quadratic complexity in destructor calls. All changes are backward-compatible. Bug Fixes \u00b6 Removed reserve() calls from the destructor which could lead to quadratic complexity. #1837 #1838 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.7.2 \u00b6 Files include.zip (274 KB) include.zip.asc (1 KB) json.hpp (791 KB) json.hpp.asc (1 KB) Release date: 2019-11-10 SHA-256: 0a65fcbbe1b334d3f45c9498e5ee28c3f3b2428aea98557da4a3ff12f0f14ad6 (json.hpp), 67f69c9a93b7fa0612dc1b6273119d2c560317333581845f358aaa68bff8f087 (include.zip) Summary \u00b6 Project bad_json_parsers tested how JSON parser libraries react on deeply nested inputs . It turns out that this library segfaulted at a certain nesting depth. This bug was fixed with this release. Now the parsing is only bounded by the available memory. All changes are backward-compatible. Bug Fixes \u00b6 Fixed a bug that lead to stack overflow for deeply nested JSON values (objects, array) by changing the implementation of the destructor from a recursive to an iterative approach. #832, #1419, #1835 Further Changes \u00b6 Added WhiteStone Bolt. #1830 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.7.1 \u00b6 Files include.zip (273 KB) include.zip.asc (1 KB) json.hpp (789 KB) json.hpp.asc (1 KB) Release date: 2019-11-06 SHA-256: b5ba7228f3c22a882d379e93d08eab4349458ee16fbf45291347994eac7dc7ce (json.hpp), 77b9f54b34e7989e6f402afb516f7ff2830df551c3a36973085e2c7a6b1045fe (include.zip) Summary \u00b6 This release fixes several small bugs in the library. All changes are backward-compatible. Bug Fixes \u00b6 Fixed a segmentation fault when serializing std::int64_t minimum value. #1708 #1722 Fixed the contains() function for JSON Pointers. #1727 #1741 Fixed too lax SFINAE guard for conversion from std::pair and std::tuple to json . #1805 #1806 #1825 #1826 Fixed some regressions detected by UBSAN. Updated CI to use Clang-Tidy 7.1.0. #1716 #1728 Fixed integer truncation in iteration_proxy . #1797 Updated Hedley to v11 to fix a E2512 error in MSVC. #1799 Fixed a compile error in enum deserialization of non non-default-constructible types. #1647 #1821 Fixed the conversion from json to std::valarray . Improvements \u00b6 The items() function can now be used with a custom string type. #1765 Made json_pointer::back const . #1764 #1769 Meson is part of the release archive. #1672 #1694 Improved documentation on the Meson and Spack package manager. #1694 #1720 Further Changes \u00b6 Added GitHub Workflow with ubuntu-latest /GCC 7.4.0 as CI step. Added GCC 9 to Travis CI to compile with C++20 support. #1724 Added MSVC 2019 to the AppVeyor CI. #1780 Added badge to fuzzing status . Fixed some cppcheck warnings. #1760 Fixed several typos in the documentation. #1720 #1767 #1803 Added documentation on the JSON_THROW_USER , JSON_TRY_USER , and JSON_CATCH_USER macros to control user-defined exception handling. Used GitHub's CODEOWNERS and SECURITY feature. Removed GLOB from CMake files. #1779 Updated to Doctest 2.3.5. Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.7.0 \u00b6 Files include.zip (143 KB) include.zip.asc (1 KB) json.hpp (782 KB) json.hpp.asc (1 KB) Release date: 2019-07-28 SHA-256: a503214947952b69f0062f572cb74c17582a495767446347ce2e452963fc2ca4 (json.hpp), 541c34438fd54182e9cdc68dd20c898d766713ad6d901fb2c6e28ff1f1e7c10d (include.zip) Summary \u00b6 This release introduces a few convenience functions and performs a lot of house keeping (bug fixes and small improvements). All changes are backward-compatible. New Features \u00b6 Add overload of the contains function to check if a JSON pointer is valid without throwing exceptions, just like its counterpart for object keys . #1600 Add a function to_string to allow for generic conversion to strings. #916 #1585 Add return value for the emplace_back function , returning a reference to the added element just like C++17 is introducing this for std::vector . #1609 Add info how to use the library with the pacman package manager on MSYS2. #1670 Bug Fixes \u00b6 Fix an issue where typedefs with certain names yielded a compilation error. #1642 #1643 Fix a conversion to std::string_view in the unit tests. #1634 #1639 Fix MSVC Debug build. #1536 #1570 #1608 Fix get_to method to clear existing content before writing. #1511 #1555 Fix a -Wc++17-extensions warning. nodiscard attributes are now only used with Clang when -std=c++17 is used. #1535 #1551 Improvements \u00b6 Switch from Catch to doctest for the unit tests which speeds up compilation and runtime of the 112,112,308 tests. Add an explicit section to the README about the frequently addressed topics character encoding , comments in JSON , and the order of object keys . Further Changes \u00b6 Use GNUInstallDirs to set library install directories. #1673 Fix links in the README . #1620 #1621 #1622 #1623 #1625 Mention json type on the documentation start page . #1616 Complete documentation of value() function with respect to type_error.302 exception. #1601 Fix links in the documentation. #1598 Add regression tests for MSVC. #1543 #1570 Use CircleCI for continuous integration . Use Doozer for continuous integration on Linux (CentOS, Raspbian, Fedora) Add tests to check each CMake flag ( JSON_BuildTests , JSON_Install , JSON_MultipleHeaders , JSON_Sanitizer , JSON_Valgrind , JSON_NoExceptions , JSON_Coverage ). Use Hedley to avoid re-inventing several compiler-agnostic feature macros like JSON_DEPRECATED , JSON_NODISCARD , JSON_LIKELY , JSON_UNLIKELY , JSON_HAS_CPP_14 , or JSON_HAS_CPP_17 . Functions taking or returning pointers are annotated accordingly when a pointer will not be null. Build and run tests on AppVeyor in DEBUG and RELEASE mode. Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.6.1 \u00b6 Files include.zip (136 KB) include.zip.asc (1 KB) json.hpp (711 KB) json.hpp.asc (1 KB) Release date: 2019-03-20 SHA-256: d2eeb25d2e95bffeb08ebb7704cdffd2e8fca7113eba9a0b38d60a5c391ea09a (json.hpp), 69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf (include.zip) Summary \u00b6 This release fixes a regression and a bug introduced by the earlier 3.6.0 release. All changes are backward-compatible. Bug Fixes \u00b6 Fixed regression of #590 which could lead to compilation errors with GCC 7 and GCC 8. #1530 Fixed a compilation error when was included. #1531 Further Changes \u00b6 Fixed a warning for missing field initializers. #1527 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.6.0 \u00b6 Files include.zip (136 KB) include.zip.asc (1 KB) json.hpp (711 KB) json.hpp.asc (1 KB) Release date: 2019-03-20 SHA-256: ce9839370f28094c71107c405affb3b08c4a098154988014cbb0800b1c44a831 (json.hpp), 237c5e66e7f8186a02804ce9dbd5f69ce89fe7424ef84adf6142e973bd9532f4 (include.zip) \u2139\ufe0f This release introduced a regression. Please update to version 3.6.1 ! Summary \u00b6 This release adds some convenience functions for JSON Pointers , introduces a contains function to check if a key is present in an object, and improves the performance of integer serialization . Furthermore, a lot of small bug fixes and improvements have been made. All changes are backward-compatible. New Features \u00b6 Overworked the public interface for JSON Pointers. The creation of JSON Pointers is simplified with operator/ and operator/= . JSON Pointers can be inspected with empty , back , and parent_pointer , and manipulated with push_back and pop_back . #1434 Added a boolean method contains to check whether an element exists in a JSON object with a given key. Returns false when called on non-object types. #1471 #1474 Bug Fixes \u00b6 Fixed a compilation issues with libc 2.12. #1483 #1514 Fixed endian conversion on PPC64. #1489 Fixed library to compile with GCC 9. #1472 #1492 Fixed a compilation issue with GCC 7 on CentOS. #1496 Fixed an integer overflow. #1447 Fixed buffer flushing in serializer. #1445 #1446 Improvements \u00b6 The performance of dumping integers has been greatly improved. #1411 Added CMake parameter JSON_Install to control whether the library should be installed (default: on). #1330 Fixed a lot of compiler and linter warnings. #1400 #1435 #1502 Reduced required CMake version from 3.8 to 3.1. #1409 #1428 #1441 #1498 Added nodiscard attribute to meta() , array() , object() , from_cbor , from_msgpack , from_ubjson , from_bson , and parse . #1433 Further Changes \u00b6 Added missing headers. #1500 Fixed typos and broken links in README. #1417 #1423 #1425 #1451 #1455 #1491 Fixed documentation of parse function. #1473 Suppressed warning that cannot be fixed inside the library. #1401 #1468 Imroved package manager suppert: Updated Buckaroo instructions. #1495 Improved Meson support. #1463 Added Conda package manager documentation. #1430 Added NuGet package manager documentation. #1132 Continuous Integration Removed unstable or deprecated Travis builders (Xcode 6.4 - 8.2) and added Xcode 10.1 builder. Added Clang 7 to Travis CI. Fixed AppVeyor x64 builds. #1374 #1414 Updated thirdparty libraries: Catch 1.12.0 -> 1.12.2 Google Benchmark 1.3.0 -> 1.4.1 Doxygen 1.8.15 -> 1.8.16 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.5.0 \u00b6 Files include.zip (133 KB) include.zip.asc (1 KB) json.hpp (693 KB) json.hpp.asc (1 KB) Release date: 2018-12-22 SHA-256: 8a6dbf3bf01156f438d0ca7e78c2971bca50eec4ca6f0cf59adf3464c43bb9d5 (json.hpp), 3564da9c5b0cf2e032f97c69baedf10ddbc98030c337d0327a215ea72259ea21 (include.zip) Summary \u00b6 This release introduces the support for structured bindings and reading from FILE* . Besides, a few bugs have been fixed. All changes are backward-compatible. New Features \u00b6 Structured bindings are now supported for JSON objects and arrays via the items() member function, so finally this code is possible: for ( auto & [ key , val ] : j . items ()) { std :: cout << key << ':' << val << '\\n' ; } #1388 #1391 Added support for reading from FILE* to support situations in which streams are nit available or would require too much RAM. #1370 #1392 Bug Fixes \u00b6 The eofbit was not set for input streams when the end of a stream was reached while parsing. #1340 #1343 Fixed a bug in the SAX parser for BSON arrays. Improvements \u00b6 Added support for Clang 5.0.1 (PS4 version). #1341 #1342 Further Changes \u00b6 Added a warning for implicit conversions to the documentation: It is not recommended to use implicit conversions when reading from a JSON value. Details about this recommendation can be found here . #1363 Fixed typos in the documentation. #1329 #1380 #1382 Fixed a C4800 warning. #1364 Fixed a -Wshadow warning #1346 Wrapped std::snprintf calls to avoid error in MSVC. #1337 Added code to allow installation via Meson. #1345 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.4.0 \u00b6 Files include.zip (132 KB) include.zip.asc (1 KB) json.hpp (689 KB) json.hpp.asc (1 KB) Release date: 2018-10-30 SHA-256: 63da6d1f22b2a7bb9e4ff7d6b255cf691a161ff49532dcc45d398a53e295835f (json.hpp), bfec46fc0cee01c509cf064d2254517e7fa80d1e7647fea37cf81d97c5682bdc (include.zip) Summary \u00b6 This release introduces three new features: BSON (Binary JSON) is next to CBOR, MessagePack, and UBJSON the fourth binary (de)serialization format supported by the library. Adjustable error handlers for invalid Unicode allows to specify the behavior when invalid byte sequences are serialized. Simplified enum/JSON mapping with a macro in case the default mapping to integers is not desired. Furthermore, some effort has been invested in improving the parse error messages . Besides, a few bugs have been fixed. All changes are backward-compatible. New Features \u00b6 The library can read and write a subset of BSON (Binary JSON) . All data types known from JSON are supported, whereas other types more tied to MongoDB such as timestamps, object ids, or binary data are currently not implemented. See the README for examples. #1244 #1320 The behavior when the library encounters an invalid Unicode sequence during serialization can now be controlled by defining one of three Unicode error handlers : (1) throw an exception (default behavior), (2) replace invalid sequences by the Unicode replacement character (U+FFFD), or (3) ignore/filter invalid sequences. See the documentation of the dump function for examples. #1198 #1314 To easily specify a user-defined enum/JSON mapping , a macro NLOHMANN_JSON_SERIALIZE_ENUM has been introduced. See the README section for more information. #1208 #1323 Bug Fixes \u00b6 fixed truncation #1286 #1315 fixed an issue with std::pair #1299 #1301 fixed an issue with std::variant #1292 #1294 fixed a bug in the JSON Pointer parser Improvements \u00b6 The diagnosis messages for parse errors have been improved: error messages now indicated line/column positions where possible (in addition to a byte count) and also the context in which the error occurred (e.g., \"while parsing a JSON string\"). Example: error parse error at 2: syntax error - invalid string: control character must be escaped; last read: '' is now reported as 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 \\t; last read: '' . #1280 #1288 #1303 Further Changes \u00b6 improved Meson documentation #1305 fixed some more linter warnings #1280 fixed Clang detection for third-party Google Benchmark library #1277 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.3.0 \u00b6 Files include.zip (123 KB) include.zip.asc (1 KB) json.hpp (635 KB) json.hpp.asc (1 KB) Release date: 2018-10-05 SHA-256: f1327bb60c58757a3dd2b0c9c45d49503d571337681d950ec621f8374bcc14d4 (json.hpp), 9588d63557333aaa485e92221ec38014a85a6134e7486fe3441e0541a5a89576 (include.zip) Summary \u00b6 This release adds support for GCC 4.8 . Furthermore, it adds a function get_to to write a JSON value to a passed reference. Another topic of this release was the CMake support which has been overworked and documented. Besides, a lot of bugs have been fixed and slight improvements have been made. All changes are backward-compatible. New Features \u00b6 The library can now also built with GCC 4.8 . Though this compiler does not fully support C++11, it can successfully compile and run the test suite. Note that bug 57824 in GCC 4.8 still forbids to use multiline raw strings in arguments to macros. #1257 Added new function get_to to write a JSON value to a passed reference. The destination type is automatically derived which allows more succinct code compared to the get function. #1227 #1231 Bug Fixes \u00b6 Fixed a bug in the CMake file that made target_link_libraries to not properly include nlohmann_json . #1243 #1245 #1260 Fixed a warning in MSVC 2017 complaining about a constexpr if. #1204 #1268 #1272 Fixed a bug that prevented compilation with ICPC. #755 #1222 Improved the SFINAE correctness to fix a bug in the conversion operator. #1237 #1238 Fixed a -Wctor-dtor-privacy warning. #1224 Fixed a warning on a lambda in unevaluated context. #1225 #1230 Fixed a bug introduced in version 3.2.0 where defining JSON_CATCH_USER led to duplicate macro definition of JSON_INTERNAL_CATCH . #1213 #1214 Fixed a bug that prevented compilation with Clang 3.4.2 in RHEL 7. #1179 #1249 Improvements \u00b6 Added documentation on CMake integration of the library. #1270 Changed the CMake file to use find_package(nlohmann_json) without installing the library. #1202 Improved error messages in case operator[] is used with the wrong combination (json.exception.type_error.305) of JSON container type and argument type. Example: \"cannot use operator[] with a string argument\". #1220 #1221 Added a license and version information to the Meson build file. #1252 Removed static assertions to indicated missing to_json or from_json functions as such assertions do not play well with SFINAE. These assertions also led to problems with GMock. #960 #1212 #1228 The test suite now does not wait forever if run in a wrong directory and input files are not found. #1262 The test suite does not show deprecation warnings for deprecated functions which frequently led to confusion. #1271 Further Changes \u00b6 GCC 4.8 and Xcode 10 were added to the continuous integration suite at Travis. Added lgtm checks to pull requests. Added tests for CMake integration. #1260 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.2.0 \u00b6 Files include.zip (124 KB) include.zip.asc (1 KB) json.hpp (636 KB) json.hpp.asc (1 KB) Release date: 2018-08-20 SHA-256: ce6b5610a051ec6795fa11c33854abebb086f0fd67c311f5921c3c07f9531b44 (json.hpp), 35ee642558b90e2f9bc758995c4788c4b4d4dec54eef95fb8f38cb4d49c8fc7c (include.zip) Summary \u00b6 This release introduces a SAX interface to the library. While this may be a very special feature used by only few people, it allowed to unify all functions that consumed input and created some kind of JSON value. Internally, now all existing functions like parse , accept , from_cbor , from_msgpack , and from_ubjson use the SAX interface with different event processors. This allowed to separate the input processing from the value generation. Furthermore, throwing an exception in case of a parse error is now optional and up to the event processor. Finally, the JSON parser is now non-recursive (meaning it does not use the call stack, but std::vector to track the hierarchy of structured values) which allows to process nested input more efficiently. Furthermore, the library finally is able to parse from wide string types . This is the first step toward opening the library from UTF-8 to UTF-16 and UTF-32. This release further fixes several bugs in the library. All changes are backward-compatible. New Features \u00b6 added a parser with a SAX interface (#971, #1153) support to parse from wide string types std::wstring , std::u16string , and std::u32string ; the input will be converted to UTF-8 (#1031) added support for std::string_view when using C++17 (#1028) allow to roundtrip std::map and std::unordered_map from JSON if key type is not convertible to string; in these cases, values are serialized to arrays of pairs (#1079, #1089, #1133, #1138) Bug Fixes \u00b6 allow to create nullptr_t from JSON allowing to properly roundtrip null values (#1169) allow compare user-defined string types (#1130) better support for algorithms using iterators from items() (#1045, #1134) added parameter to avoid compilation error with MSVC 2015 debug builds (#1114) re-added accidentally skipped unit tests (#1176) fixed MSVC issue with std::swap (#1168) Improvements \u00b6 key() function for iterators returns a const reference rather than a string copy (#1098) binary formats CBOR, MessagePack, and UBJSON now supports float as type for floating-point numbers (#1021) Further Changes \u00b6 changed issue templates improved continuous integration: added builders for Xcode 9.3 and 9.4, added builders for GCC 8 and Clang 6, added builder for MinGW, added builders for MSVC targeting x86 required CMake version is now at least 3.8 (#1040) overworked CMake file wrt. packaging (#1048) added package managers: Spack (#1041) and CocoaPods (#1148) fixed Meson include directory (#1142) preprocessor macro JSON_SKIP_UNSUPPORTED_COMPILER_CHECK can skip the rejection of unsupported compilers - use at your own risk! (#1128) preprocessor macro JSON_INTERNAL_CATCH / JSON_INTERNAL_CATCH_USER allows to control the behavior of exception handling inside the library (#1187) added note on char to JSON conversion added note how to send security-related issue via encrypted email removed dependency to std::stringstream (#1117) added SPDX-License-Identifier added updated JSON Parsing Test Suite, described in Parsing JSON is a Minefield \ud83d\udca3 updated to Catch 1.12.0 Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.1.2 \u00b6 Files include.zip (115 KB) include.zip.asc (1 KB) json.hpp (582 KB) json.hpp.asc (1 KB) Release date: 2018-03-14 SHA-256: fbdfec4b4cf63b3b565d09f87e6c3c183bdd45c5be1864d3fcb338f6f02c1733 (json.hpp), 495362ee1b9d03d9526ba9ccf1b4a9c37691abe3a642ddbced13e5778c16660c (include.zip) Summary \u00b6 This release fixes several bugs in the library. All changes are backward-compatible. Bug Fixes \u00b6 Fixed a memory leak occurring in the parser callback (#1001). Different specializations of basic_json (e.g., using different template arguments for strings or objects) can now be used in assignments (#972, #977, #986). Fixed a logical error in an iterator range check (#992). Improvements \u00b6 The parser and the serialization now support user-defined string types (#1006, #1009). Further Changes \u00b6 Clang Analyzer is now used as additional static analyzer; see make clang_analyze . Overworked README by adding links to the documentation (#981). Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.1.1 \u00b6 Files include.zip (114 KB) include.zip.asc (1 KB) json.hpp (577 KB) json.hpp.asc (1 KB) Release date: 2018-02-13 SHA-256: e14ce5e33d6a2daf748026bd4947f3d9686ca4cfd53d10c3da46a0a9aceb7f2e (json.hpp), fde771d4b9e4f222965c00758a2bdd627d04fb7b59e09b7f3d1965abdc848505 (include.zip) Summary \u00b6 This release fixes several bugs in the library. All changes are backward-compatible. Bug Fixes \u00b6 Fixed parsing of CBOR strings with indefinite length (#961). Earlier versions of this library misinterpreted the CBOR standard and rejected input with the 0x7F start byte. Fixed user-defined conversion to vector type (#924, #969). A wrong SFINAE check rejected code though a user-defined conversion was provided. Fixed documentation of the parser behavior for objects with duplicate keys (#963). The exact behavior is not specified by RFC 8259 and the library now also provides no guarantee which object key is stored. Added check to detect memory overflow when parsing UBJSON containers (#962). The optimized UBJSON format allowed for specifying an array with billions of null elements with a few bytes and the library did not check whether this size exceeded max_size() . Further Changes \u00b6 Code coverage is now calculated for the individual header files, allowing to find uncovered lines more quickly than by browsing through the single header version (#953, #957). A Makefile target run_benchmarks was added to quickly build and run the benchmark suite. The documentation was harmonized with respect to the header inclusion (#955). Now all examples and the README use #include to allow for selecting single_include or include or whatever installation folder as include directory. Added note on how to use the library with the cget package manager (#954). Deprecated functions \u00b6 This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.1.0 \u00b6 Files include.zip (114 KB) include.zip.asc (1 KB) json.hpp (577 KB) json.hpp.asc (1 KB) Release date: 2018-02-01 SHA-256: d40f614d10a6e4e4e80dca9463da905285f20e93116c36d97d4dc1aa63d10ba4 (json.hpp), 2b7234fca394d1e27b7e017117ed80b7518fafbb4f4c13a7c069624f6f924673 (include.zip) Summary \u00b6 This release adds support for the UBJSON format and JSON Merge Patch . It also contains some minor changes and bug fixes. All changes are backward-compatible. New features \u00b6 The library now supports UBJSON (Universal Binary JSON Specification) as binary format to read and write JSON values space-efficiently. See the documentation overview for a comparison of the different formats CBOR, MessagePack, and UBJSON. JSON Merge Patch (RFC 7386) offers an intuitive means to describe patches between JSON values (#876, #877). See the documentation of merge_patch for more information. Improvements \u00b6 The library now uses the Grisu2 algorithm for printing floating-point numbers (based on the reference implementation by Florian Loitsch) which produces a short representation which is guaranteed to round-trip (#360, #935, #936). The UTF-8 handling was further simplified by using the decoder of Bj\u00f6rn Hoehrmann in more scenarios. Reorganization \u00b6 Though the library is released as a single header, its development got more and more complicated. With this release, the header is split into several files and the single-header file json.hpp can be generated from these development sources. In the repository, folder include contains the development sources and single_include contains the single json.hpp header (#700, #906, #907, #910, #911, #915, #920, #924, #925, #928, #944). The split further allowed for a forward declaration header include/nlohmann/json_fwd.hpp to speed up compilation times (#314). Further changes \u00b6 Google Benchmark is now used for micro benchmarks (see benchmarks folder, #921). The serialization (JSON and binary formats) now properly work with the libraries string template parameter, allowing for optimized string implementations to be used in constraint environments such as embedded software (#941, #950). The exceptional behavior can now be overridden by defining macros JSON_THROW_USER , JSON_TRY_USER , and JSON_CATCH_USER , defining the behavior of throw , try and catch , respectively. This allows to switch off C++'s exception mechanism yet still execute user-defined code in case an error condition occurs (#938). To facilitate the interplay with flex and Bison , the library does not use the variable name yytext any more as it could clash with macro definitions (#933). The library now defines NLOHMANN_JSON_VERSION_MAJOR , NLOHMANN_JSON_VERSION_MINOR , and NLOHMANN_JSON_VERSION_PATCH to allow for conditional compilation based on the included library version (#943, #948). A compilation error with ICC has been fixed (#947). Typos and links in the documentation have been fixed (#900, #930). A compiler error related to incomplete types has been fixed (#919). The tests form the UTF-8 decoder stress test have been added to the test suite. Deprecated functions \u00b6 Function iterator_wrapper has been deprecated (#874). Since its introduction, the name was up for discussion, as it was too technical. We now introduced the member function items() with the same semantics. iterator_wrapper will be removed in the next major version (i.e., 4.0.0). Furthermore, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0): friend std::istream& operator<<(basic_json&, std::istream&) friend std::ostream& operator>>(const basic_json&, std::ostream&) Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.0.1 \u00b6 Files json.hpp (502 KB) json.hpp.asc (1 KB) Release date: 2017-12-29 SHA-256: c9b3591f1bb94e723a0cd7be861733a3a555b234ef132be1e9027a0364118c4c Summary \u00b6 This release fixes small issues in the implementation of JSON Pointer and JSON Patch . All changes are backward-compatible. Changes \u00b6 The \"copy\" operation of JSON Patch ( RFC 6902 ) requests that it is an error if the target path points into a non-existing array or object (see #894 for a detailed description). This release fixes the implementation to detect such invalid target paths and throw an exception. An array index in a JSON Pointer ( RFC 6901 ) must be an integer. This release fixes the implementation to throw an exception in case invalid array indices such as 10e2 are used. Added the JSON Patch tests from Byron Ruth and Mike McCabe. Fixed the documentation of the at(ptr) function with JSON Pointers to list all possible exceptions (see #888). Updated the container overview documentation (see #883). The CMake files now respect the BUILD_TESTING option (see #846, #885) Fixed some compiler warnings (see #858, #882). Deprecated functions \u00b6 To unify the interfaces and to improve similarity with the STL, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0): friend std::istream& operator<<(basic_json&, std::istream&) friend std::ostream& operator>>(const basic_json&, std::ostream&) Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. v3.0.0 \u00b6 Files json.hpp (501 KB) json.hpp.asc (1 KB) Release date: 2017-12-17 SHA-256: 076d4a0cb890a3c3d389c68421a11c3d77c64bd788e85d50f1b77ed252f2a462 Summary \u00b6 After almost a year, here is finally a new release of JSON for Modern C++, and it is a major one! As we adhere to semantic versioning , this means the release includes some breaking changes, so please read the next section carefully before you update. But don't worry, we also added a few new features and put a lot of effort into fixing a lot of bugs and straighten out a few inconsistencies. Breaking changes \u00b6 This section describes changes that change the public API of the library and may require changes in code using a previous version of the library. In section \"Moving from 2.x.x to 3.0.0\" at the end of the release notes, we describe in detail how existing code needs to be changed. The library now uses user-defined exceptions instead of re-using those defined in (#244). This not only allows to add more information to the exceptions (every exception now has an identifier, and parse errors contain the position of the error), but also to easily catch all library exceptions with a single catch(json::exception) . When strings with a different encoding as UTF-8 were stored in JSON values, their serialization could not be parsed by the library itself, as only UTF-8 is supported. To enforce this library limitation and improve consistency, non-UTF-8 encoded strings now yield a json::type_error exception during serialization (#838). The check for valid UTF-8 is realized with code from Bj\u00f6rn Hoehrmann . NaN and infinity values can now be stored inside the JSON value without throwing an exception. They are, however, still serialized as null (#388). The library's iterator tag was changed from RandomAccessIterator to BidirectionalIterator (#593). Supporting RandomAccessIterator was incorrect as it assumed an ordering of values in a JSON objects which are unordered by definition. The library does not include the standard headers , , and any more. You may need to add these headers to code relying on them. Removed constructor explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr) which was deprecated in version 2.0.0 (#480). Deprecated functions \u00b6 To unify the interfaces and to improve similarity with the STL, the following functions are now deprecated and will be removed in the next major version (i.e., 4.0.0): friend std::istream& operator<<(basic_json&, std::istream&) friend std::ostream& operator>>(const basic_json&, std::ostream&) Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead. New features \u00b6 With all this breaking and deprecation out of the way, let's talk about features! We improved the diagnostic information for syntax errors (#301). Now, an exception json::parse_error is thrown which contains a detailed message on the error, but also a member byte to indicate the byte offset in the input where the error occurred. We added a non-throwing syntax check (#458): The new accept function returns a Boolean indicating whether the input is proper JSON. We also added a Boolean parameter allow_exceptions to the existing parse functions to return a discarded value in case a syntax error occurs instead of throwing an exception. An update function was added to merge two JSON objects (#428). In case you are wondering: the name was inspired by Python . The insert function now also supports an iterator range to add elements to an object. The binary exchange formats CBOR and MessagePack can now be parsed from input streams and written to output streams (#477). Input streams are now only read until the end of a JSON value instead of the end of the input (#367). The serialization function dump now has two optional parameters ensure_ascii to escape all non-ASCII characters with \\uxxxx and an indent_char parameter to choose whether to indent with spaces or tabs (#654). Added built-in type support for C arrays (#502), std::pair and std::tuple (#563, #614), enum and enum class (#545), std::vector (#494). Fixed support for std::valarray (#702), std::array (#553), and std::map (#600, #607). Further changes \u00b6 Furthermore, there have been a lot of changes under the hood: Replaced the re2c generated scanner by a self-coded version which allows for a better modularization of the parser and better diagnostics. To test the new scanner, we added millions (8,860,608 to be exact) of unit tests to check all valid and invalid byte sequences of the Unicode standard. Google's OSS-Fuzz is still constantly fuzz-testing the library and found several issues that were fixed in this release (#497, #504, #514, #516, #518, #519, #575). We now also ignore UTF-8 byte order marks when parsing from an iterator range (#602). Values can be now moved from initializer lists (#663). Updated to Catch 1.9.7. Unfortunately, Catch2 currently has some performance issues. The non-exceptional paths of the library are now annotated with __builtin_expect to optimize branch prediction as long as no error occurs. MSVC now produces a stack trace in MSVC if a from_json or to_json function was not found for a user-defined type. We also added a debug visualizer nlohmann_json.natvis for better debugging in MSVC (#844). Overworked the documentation and added even more examples. The build workflow now relies on CMake and CTest. Special flags can be chosen with CMake, including coverage ( JSON_Coverage ), compilation without exceptions ( JSON_NoExceptions ), LLVM sanitizers ( JSON_Sanitizer ), or execution with Valgrind ( JSON_Valgrind ). Added support for package managers Meson (#576), Conan (#566), Hunter (#671, #829), and vcpkg (#753). Added CI builders: Xcode 8.3, 9.0, 9.1, and 9.2; GCC 7.2; Clang 3.8, 3.9, 4.0, and 5.0; Visual Studio 2017. The library is further built with C++17 settings on the latest Clang, GCC, and MSVC version to quickly detect new issues. Moving from 2.x.x to 3.0.0 \u00b6 User-defined Exceptions \u00b6 There are five different exceptions inheriting from json::exception : json::parse_error for syntax errors (including the binary formats), json::invalid_iterator for errors related to iterators, json::type_error for errors where functions were called with the wrong JSON type, json::out_of_range for range errors, and json::other_error for miscellaneous errors. To support these exception, the try / catch blocks of your code need to be adjusted: new exception previous exception parse_error.101 invalid_argument parse_error.102 invalid_argument parse_error.103 invalid_argument parse_error.104 invalid_argument parse_error.105 invalid_argument parse_error.106 domain_error parse_error.107 domain_error parse_error.108 domain_error parse_error.109 invalid_argument parse_error.110 out_of_range parse_error.111 invalid_argument parse_error.112 invalid_argument invalid_iterator.201 domain_error invalid_iterator.202 domain_error invalid_iterator.203 domain_error invalid_iterator.204 out_of_range invalid_iterator.205 out_of_range invalid_iterator.206 domain_error invalid_iterator.207 domain_error invalid_iterator.208 domain_error invalid_iterator.209 domain_error invalid_iterator.210 domain_error invalid_iterator.211 domain_error invalid_iterator.212 domain_error invalid_iterator.213 domain_error invalid_iterator.214 out_of_range type_error.301 domain_error type_error.302 domain_error type_error.303 domain_error type_error.304 domain_error type_error.305 domain_error type_error.306 domain_error type_error.307 domain_error type_error.308 domain_error type_error.309 domain_error type_error.310 domain_error type_error.311 domain_error type_error.313 domain_error type_error.314 domain_error type_error.315 domain_error out_of_range.401 out_of_range out_of_range.402 out_of_range out_of_range.403 out_of_range out_of_range.404 out_of_range out_of_range.405 domain_error other_error.501 domain_error Handling of NaN and INF \u00b6 If an overflow occurs during parsing a number from a JSON text, an exception json::out_of_range is thrown so that the overflow is detected early and roundtripping is guaranteed. NaN and INF floating-point values can be stored in a JSON value and are not replaced by null. That is, the basic_json class behaves like double in this regard (no exception occurs). However, NaN and INF are serialized to null . Removal of deprecated functions \u00b6 Function explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr) should be replaced by the parse function: Let ss be a stream and cb be a parse callback function. Old code: json j ( ss , cb ); New code: json j = json :: parse ( ss , cb ); If no callback function is used, also the following code works: json j ; j << ss ; or json j ; ss >> j ; v2.1.1 \u00b6 Files json.hpp (437 KB) json.hpp.asc (1 KB) Release date: 2017-02-25 SHA-256: faa2321beb1aa7416d035e7417fcfa59692ac3d8c202728f9bcc302e2d558f57 Summary \u00b6 This release fixes a locale-related bug in the parser . To do so, the whole number handling (lexer, parser, and also the serialization) have been overworked. Furthermore, a lot of small changes added up that were added to this release. All changes are backward-compatible. Changes \u00b6 Locales that have a different character than . as decimal separator (e.g., the Norwegian locale nb_NO.UTF-8 ) led to truncated number parsing or parse errors. The library now has been fixed to work with any locale . Note that . is still the only valid decimal separator for JSON input. Numbers like 1.0 were correctly parsed as floating-point number, but serialized as integer ( 1 ). Now, floating-point numbers correctly round trip . Parsing incorrect JSON numbers with leading 0 ( 0123 ) could yield a buffer overflow . This is fixed now by detecting such errors directly by the lexer. Constructing a JSON value from a pointer was incorrectly interpreted as a Boolean; such code will now yield a compiler error. Comparing a JSON number with 0 led to a comparison with null . This is fixed now. All throw calls are now wrapped in macros. Starting during the preparation of this release (since 8 February 2017), commits and released files are cryptographically signed with this GPG key . Previous releases have also been signed. The parser for MessagePack and CBOR now supports an optional start index parameter to define a byte offset for the parser. Some more warnings have been fixed. With Clang, the code compiles without warnings with -Weverything (well, it needs -Wno-documentation-unknown-command and -Wno-deprecated-declarations , but you get the point). The code can be compiled easier with many Android NDKs by avoiding macros like UINT8_MAX which previously required defining a preprocessor macro for compilation. The unit tests now compile two times faster. Cotire is used to speed up the build. Fixed a lot of typos in the documentation. Added a section to the README file that lists all used third-party code/tools . Added a note on constructing a string value vs. parsing. The test suite now contains 11202597 unit tests. Improved the Doxygen documentation by shortening the template parameters of class basic_json . Removed Doozer. Added Codacity. Upgraded Catch to version 1.7.2. v2.1.0 \u00b6 Files json.hpp (426 KB) json.hpp.asc (1 KB) Release date: 2017-01-28 SHA-256: a571dee92515b685784fd527e38405cf3f5e13e96edbfe3f03d6df2e363a767b Summary \u00b6 This release introduces a means to convert from/to user-defined types. The release is backwards compatible. Changes \u00b6 The library now offers an elegant way to convert from and to arbitrary value types . All you need to do is to implement two functions: to_json and from_json . Then, a conversion is as simple as putting a = between variables. See the README for more information and examples. Exceptions can now be switched off. This can be done by defining the preprocessor symbol JSON_NOEXCEPTION or by passing -fno-exceptions to your compiler. In case the code would usually thrown an exception, abort() is now called. Information on the library can be queried with the new (static) function meta() which returns a JSON object with information on the version, compiler, and platform. See the documentation for an example. A bug in the CBOR parser was fixed which led to a buffer overflow. The function type_name() is now public. It allows to query the type of a JSON value as string. Added the Big List of Naughty Strings as test case. Updated to Catch v1.6.0 . Some typos in the documentation have been fixed. v2.0.10 \u00b6 Files json.hpp (409 KB) json.hpp.asc (1 KB) Release date: 2017-01-02 SHA-256: ec27d4e74e9ce0f78066389a70724afd07f10761009322dc020656704ad5296d Summary \u00b6 This release fixes several security-relevant bugs in the MessagePack and CBOR parsers. The fixes are backwards compatible. Changes \u00b6 Fixed a lot of bugs in the CBOR and MesssagePack parsers . These bugs occurred if invalid input was parsed and then could lead in buffer overflows. These bugs were found with Google's OSS-Fuzz , see #405, #407, #408, #409, #411, and #412 for more information. We now also use the Doozer continuous integration platform . The complete test suite is now also run with Clang's address sanitizer and undefined-behavior sanitizer . Overworked fuzz testing ; CBOR and MessagePack implementations are now fuzz-tested. Furthermore, all fuzz tests now include a round trip which ensures created output can again be properly parsed and yields the same JSON value. Clarified documentation of find() function to always return end() when called on non-object value types. Moved thirdparty test code to test/thirdparty directory. v2.0.9 \u00b6 Files json.hpp (406 KB) json.hpp.asc (1 KB) Release date: 2016-12-16 SHA-256: fbf3396f13e187d6c214c297bddc742d918ea9b55e10bfb3d9f458b9bfdc22e5 Summary \u00b6 This release implements with CBOR and MessagePack two binary serialization/deserialization formats . It further contains some small fixes and improvements. The fixes are backwards compatible. Changes \u00b6 The library can now read and write the binary formats CBOR (Concise Binary Object Representation) and MessagePack . Both formats are aimed to produce a very compact representation of JSON which can be parsed very efficiently. See the README file for more information and examples. simplified the iteration implementation allowing to remove dozens of lines of code fixed an integer overflow error detected by Google's OSS-Fuzz suppressed documentation warnings inside the library to facilitate compilation with -Wdocumentation fixed an overflow detection error in the number parser updated contribution guidelines to a list of frequentely asked features that will most likely be never added to the library added a table of contents to the README file to add some structure mentioned the many examples and the documentation in the README file split unit tests into individual independent binaries to speed up compilation and testing the test suite now contains 11201886 tests v2.0.8 \u00b6 Files json.hpp (360 KB) json.hpp.asc (1 KB) Release date: 2016-12-02 SHA-256: b70db0ad34f8e0e61dc3f0cbab88099336c9674c193d8a3439d93d6aca2d7120 Summary \u00b6 This release combines a lot of small fixes and improvements. The fixes are backwards compatible. Changes \u00b6 fixed a bug that froze the parser if a passed file was not found (now, std::invalid_argument is thrown) fixed a bug that lead to an error of a file at EOF was parsed again (now, std::invalid_argument is thrown) the well known functions emplace and emplace_back have been added to JSON values and work as expected improved the performance of the serialization ( dump function) improved the performance of the deserialization (parser) some continuous integration images at Travis were added and retired; see here for the current continuous integration setup the Coverity scan works again the benchmarking code has been improved to produce more stable results the README file has been extended and includes more frequently asked examples the test suite now contains 8905518 tests updated Catch to version 1.5.8 v2.0.7 \u00b6 Files json.hpp (355 KB) json.hpp.asc (1 KB) Release date: 2016-11-02 SHA-256: 5545c323670f8165bae90b9dc6078825e86ec310d96cc4e5b47233ea43715bbf Summary \u00b6 This release fixes a few bugs in the JSON parser found in the Parsing JSON is a Minefield \ud83d\udca3 article. The fixes are backwards compatible. Changes \u00b6 The article Parsing JSON is a Minefield \ud83d\udca3 discusses a lot of pitfalls of the JSON specification. When investigating the published test cases, a few bugs in the library were found and fixed: Files with less than 5 bytes can now be parsed without error. The library now properly rejects any file encoding other than UTF-8. Furthermore, incorrect surrogate pairs are properly detected and rejected. The library now accepts all but one \"yes\" test (y_string_utf16.json): UTF-16 is not supported. The library rejects all but one \"no\" test (n_number_then_00.json): Null bytes are treated as end of file instead of an error. This allows to parse input from null-terminated strings. The string length passed to a user-defined string literal is now exploited to choose a more efficient constructor. A few grammar mistakes in the README file have been fixed. v2.0.6 \u00b6 Files json.hpp (349 KB) json.hpp.asc (1 KB) Release date: 2016-10-15 SHA256: 459cc93d5e2f503e50c6d5876eb86bfea7daf405f5a567c5a2c9abc2383756ae Summary \u00b6 This release fixes the semantics of operator[] for JSON Pointers (see below). This fix is backwards compatible. Changes \u00b6 operator[] for JSON Pointers now behaves like the other versions of operator[] and transforms null values into objects or arrays if required. This allows to created nested structures like j[\"/foo/bar/2\"] = 17 (yielding {\"foo\": \"bar\": [null, null, 17]} ) without problems. overworked a helper SFINAE function fixed some documentation issues fixed the CMake files to allow to run the test suite outside the main project directory restored test coverage to 100%. v2.0.5 \u00b6 Files json.hpp (347 KB) json.hpp.asc (1 KB) Release date: 2016-09-14 SHA-256: 8b7565263a44e2b7d3b89808bc73d2d639037ff0c1f379e3d56dbd77e00b98d9 Summary \u00b6 This release fixes a regression bug in the stream parser (function parse() and the << / >> operators). This fix is backwards compatible. Changes \u00b6 Bug fix : The end of a file stream was not detected properly which led to parse errors. This bug should have been fixed with 2.0.4, but there was still a flaw in the code. v2.0.4 \u00b6 Files json.hpp (347 KB) json.hpp.asc (1 KB) Release date: 2016-09-11 SHA-256: 632ceec4c25c4e2153f71470d3a2b992c8355f6d8b4d627d05dd16095cd3aeda Summary \u00b6 This release fixes a bug in the stream parser (function parse() and the << / >> operators). This fix is backwards compatible. Changes \u00b6 Bug fix : The end of a file stream was not detected properly which led to parse errors. Fixed a compiler warning about an unused variable. v2.0.3 \u00b6 Files json.hpp (347 KB) json.hpp.asc (1 KB) Release date: 2016-08-31 SHA-256: 535b73efe5546fde9e763c14aeadfc7b58183c0b3cd43c29741025aba6cf6bd3 Summary \u00b6 This release combines a lot of small fixes and improvements. The release is backwards compatible. Changes \u00b6 The parser/deserialization functions have been generalized to process any contiguous sequence of 1-byte elements (e.g., char , unsigned char , uint8_t ). This includes all kind of string representations (string literals, char arrays, std::string , const char* ), contiguous containers (C-style arrays, std::vector , std::array , std::valarray , std::initializer_list ). User-defined containers providing random-access iterator access via std::begin and std::end can be used as well. See the documentation ( 1 , 2 , 3 , 4 ) for more information. Note that contiguous storage cannot be checked at compile time; if any of the parse functions are called with a noncompliant container, the behavior is undefined and will most likely yield segmentation violation. The preconditions are enforced by an assertion unless the library is compiled with preprocessor symbol NDEBUG . As a general remark on assertions : The library uses assertions to preclude undefined behavior. A prominent example for this is the operator[] for const JSON objects. The behavior of this const version of the operator is undefined if the given key does not exist in the JSON object, because unlike the non-const version, it cannot add a null value at the given key. Assertions can be switched of by defining the preprocessor symbol NDEBUG . See the documentation of assert for more information. In the course of cleaning up the parser/deserialization functions, the constructor basic_json(std::istream&, const parser_callback_t) has been deprecated and will be deleted with the next major release 3.0.0 to unify the interface of the library. Deserialization will be done by stream operators or by calling one of the parse functions. That is, calls like json j(i); for an input stream i need to be replaced by json j = json::parse(i); . Compilers will produce a deprecation warning if client code uses this function. Minor improvements: Improved the performance of the serialization by avoiding the re-creation of a locale object. Fixed two MSVC warnings. Compiling the test suite with /Wall now only warns about non-inlined functions (C4710) and the deprecation of the constructor from input-stream (C4996). Some project internals: The project has qualified for the Core Infrastructure Initiative Best Practices Badge . While most requirements where already satisfied, some led to a more explicit documentation of quality-ensuring procedures. For instance, static analysis is now executed with every commit on the build server. Furthermore, the contribution guidelines document how to communicate security issues privately. The test suite has been overworked and split into several files to allow for faster compilation and analysis. The execute the test suite, simply execute make check . The continuous integration with Travis was extended with Clang versions 3.6.0 to 3.8.1 and now includes 18 different compiler/OS combinations. An 11-day run of American fuzzy lop checked 962 million inputs on the parser and found no issue. v2.0.2 \u00b6 Files json.hpp (338 KB) json.hpp.asc (1 KB) Release date: 2016-07-31 SHA-256: 8e97b7965b4594b00998d6704465412360e1a0ed927badb51ded8b82291a8f3d Summary \u00b6 This release combines a lot of small fixes and improvements. The release is backwards compatible. Changes \u00b6 The parser has been overworked, and a lot of small issues have been fixed: Improved parser performance by avoiding recursion and using move semantics for the return value. Unescaped control characters \\x10 - \\x1f are not accepted any more. Fixed a bug in the parser when reading from an input stream. Improved test case coverage for UTF-8 parsing: now, all valid Unicode code points are tested both escaped and unescaped. The precision of output streams is now preserved by the parser. Started to check the code correctness by proving termination of important loops. Furthermore, individual assertions have been replaced by a more systematic function which checks the class invariants. Note that assertions should be switched off in production by defining the preprocessor macro NDEBUG , see the documentation of assert . A lot of code cleanup : removed unused headers, fixed some compiler warnings, and fixed a build error for Windows-based Clang builds. Added some compile-time checks: Unsupported compilers are rejected during compilation with an #error command. Static assertion prohibits code with incompatible pointer types used in get_ptr() . Improved the documentation , and adjusted the documentation script to choose the correct version of sed . Replaced a lot of \"raw loops\" by STL functions like std::all_of , std::for_each , or std::accumulate . This facilitates reasoning about termination of loops and sometimes allowed to simplify functions to a single return statement. Implemented a value() function for JSON pointers (similar to at function). The Homebrew formula (see Integration ) is now tested for all Xcode builds (6.1 - 8.x) with Travis. Avoided output to std::cout in the test cases. v2.0.1 \u00b6 Files json.hpp (321 KB) json.hpp.asc (1 KB) Release date: 2016-06-28 SHA-256: ef550fcd7df572555bf068e9ec4e9d3b9e4cdd441cecb0dcea9ea7fd313f72dd Summary \u00b6 This release fixes a performance regression in the JSON serialization (function dump() ). This fix is backwards compatible. Changes \u00b6 The locale of the output stream (or the internal string stream if a JSON value is serialized to a string) is now adjusted once for the whole serialization instead of for each floating-point number. The locale of an output stream is now correctly reset to the previous value by the JSON library. v2.0.0 \u00b6 Files json.hpp (321 KB) json.hpp.asc (1 KB) Release date: 2016-06-24 SHA-256: ac9e1fb25c2ac9ca5fc501fcd2fe3281fe04f07018a1b48820e7b1b11491bb6c Summary \u00b6 This release adds several features such as JSON Pointers, JSON Patch, or support for 64 bit unsigned integers. Furthermore, several (subtle) bugs have been fixed. As noexcept and constexpr specifier have been added to several functions, the public API has effectively been changed in a (potential) non-backwards compatible manner. As we adhere to Semantic Versioning , this calls for a new major version, so say hello to 2\ufe0f\u20e3.0\ufe0f\u20e3.0\ufe0f\u20e3. Changes \u00b6 \ud83d\udd1f A JSON value now uses uint64_t (default value for template parameter NumberUnsignedType ) as data type for unsigned integer values. This type is used automatically when an unsigned number is parsed. Furthermore, constructors, conversion operators and an is_number_unsigned() test have been added. \ud83d\udc49 JSON Pointer ( RFC 6901 ) support: A JSON Pointer is a string (similar to an XPath expression) to address a value inside a structured JSON value. JSON Pointers can be used in at() and operator[] functions. Furthermore, JSON values can be \u201cflattened\u201d to key/value pairs using flatten() where each key is a JSON Pointer. The original value can be restored by \u201cunflattening\u201d the flattened value using unflatten() . \ud83c\udfe5 JSON Patch ( RFC 6902 ) support. A JSON Patch is a JSON value that describes the required edit operations (add, change, remove, \u2026) to transform a JSON value into another one. A JSON Patch can be created with function diff(const basic_json&) and applied with patch(const basic_json&) . Note the created patches use a rather primitive algorithm so far and leave room for improvement. \ud83c\uddea\ud83c\uddfa The code is now locale-independent : Floating-point numbers are always serialized with a period ( . ) as decimal separator and ignores different settings from the locale. \ud83c\udf7a Homebrew support: Install the library with brew tap nlohmann/json && brew install nlohmann_json . Added constructor to create a JSON value by parsing a std::istream (e.g., std::stringstream or std::ifstream ). Added noexcept specifier to basic_json(boolean_t) , basic_json(const number_integer_t) , basic_json(const int) , basic_json(const number_float_t) , iterator functions ( begin() , end() , etc.) When parsing numbers, the sign of 0.0 (vs. -0.0 ) is preserved. Improved MSVC 2015, Android, and MinGW support. See README for more information. Improved test coverage (added 2,225,386 tests). Removed some misuses of std::move . Fixed several compiler warnings. Improved error messages from JSON parser. Updated to re2c to version 0.16 to use a minimal DFAs for the lexer. Updated test suite to use Catch version 1.5.6. Made type getters ( is_number , etc.) and const value access constexpr . Functions push_back and operator+= now work with key/value pairs passed as initializer list, e.g. j_object += {\"key\", 1} . Overworked CMakeLists.txt to make it easier to integrate the library into other projects. Notes \u00b6 Parser error messages are still very vague and contain no information on the error location. The implemented diff function is rather primitive and does not create minimal diffs. The name of function iteration_wrapper may change in the future and the function will be deprecated in the next release. Roundtripping (i.e., parsing a JSON value from a string, serializing it, and comparing the strings) of floating-point numbers is not 100% accurate. Note that RFC 8259 defines no format to internally represent numbers and states not requirement for roundtripping. Nevertheless, benchmarks like Native JSON Benchmark treat roundtripping deviations as conformance errors. v1.1.0 \u00b6 Files json.hpp (257 KB) json.hpp.asc (1 KB) Release date: 2016-01-24 SHA-256: c0cf0e3017798ca6bb18e757ebc570d21a3bdac877845e2b9e9573d183ed2f05 Summary \u00b6 This release fixes several small bugs and adds functionality in a backwards-compatible manner. Compared to the last version (1.0.0) , the following changes have been made: Changes \u00b6 Fixed : Floating-point numbers are now serialized and deserialized properly such that rountripping works in more cases. [#185, #186, #190, #191, #194] Added : The code now contains assertions to detect undefined behavior during development. As the standard function assert is used, the assertions can be switched off by defining the preprocessor symbol NDEBUG during compilation. [#168] Added : It is now possible to get a reference to the stored values via the newly added function get_ref() . [#128, #184] Fixed : Access to object values via keys ( operator[] ) now works with all kind of string representations. [#171, #189] Fixed : The code now compiles again with Microsoft Visual Studio 2015 . [#144, #167, #188] Fixed : All required headers are now included. Fixed : Typos and other small issues. [#162, #166, #175, #177, #179, #180] Notes \u00b6 There are still known open issues (#178, #187) which will be fixed in version 2.0.0. However, these fixes will require a small API change and will not be entirely backwards-compatible. v1.0.0 \u00b6 Files json.hpp (243 KB) json.hpp.asc (1 KB) Release date: 2015-12-28 SHA-256: 767dc2fab1819d7b9e19b6e456d61e38d21ef7182606ecf01516e3f5230446de Summary \u00b6 This is the first official release. Compared to the prerelease version 1.0.0-rc1 , only a few minor improvements have been made: Changes \u00b6 Changed : A UTF-8 byte order mark is silently ignored. Changed : sprintf is no longer used. Changed : iterator_wrapper also works for const objects; note: the name may change! Changed : Error messages during deserialization have been improved. Added : The parse function now also works with type std::istream&& . Added : Function value(key, default_value) returns either a copy of an object's element at the specified key or a given default value if no element with the key exists. Added : Public functions are tagged with the version they were introduced. This shall allow for better versioning in the future. Added : All public functions and types are documented (see http://nlohmann.github.io/json/doxygen/ ) including executable examples. Added : Allocation of all types (in particular arrays, strings, and objects) is now exception-safe. Added : They descriptions of thrown exceptions have been overworked and are part of the tests suite and documentation.","title":"Releases"},{"location":"home/releases/#releases","text":"","title":"Releases"},{"location":"home/releases/#v373","text":"Files include.zip (274 KB) include.zip.asc (1 KB) json.hpp (791 KB) json.hpp.asc (1 KB) Release date: 2019-11-17 SHA-256: 3b5d2b8f8282b80557091514d8ab97e27f9574336c804ee666fda673a9b59926 (json.hpp), 87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014 (include.zip)","title":"v3.7.3"},{"location":"home/releases/#summary","text":"This release fixes a bug introduced in release 3.7.2 which could yield quadratic complexity in destructor calls. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#bug-fixes","text":"Removed reserve() calls from the destructor which could lead to quadratic complexity. #1837 #1838","title":"Bug Fixes"},{"location":"home/releases/#deprecated-functions","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v372","text":"Files include.zip (274 KB) include.zip.asc (1 KB) json.hpp (791 KB) json.hpp.asc (1 KB) Release date: 2019-11-10 SHA-256: 0a65fcbbe1b334d3f45c9498e5ee28c3f3b2428aea98557da4a3ff12f0f14ad6 (json.hpp), 67f69c9a93b7fa0612dc1b6273119d2c560317333581845f358aaa68bff8f087 (include.zip)","title":"v3.7.2"},{"location":"home/releases/#summary_1","text":"Project bad_json_parsers tested how JSON parser libraries react on deeply nested inputs . It turns out that this library segfaulted at a certain nesting depth. This bug was fixed with this release. Now the parsing is only bounded by the available memory. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#bug-fixes_1","text":"Fixed a bug that lead to stack overflow for deeply nested JSON values (objects, array) by changing the implementation of the destructor from a recursive to an iterative approach. #832, #1419, #1835","title":"Bug Fixes"},{"location":"home/releases/#further-changes","text":"Added WhiteStone Bolt. #1830","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_1","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v371","text":"Files include.zip (273 KB) include.zip.asc (1 KB) json.hpp (789 KB) json.hpp.asc (1 KB) Release date: 2019-11-06 SHA-256: b5ba7228f3c22a882d379e93d08eab4349458ee16fbf45291347994eac7dc7ce (json.hpp), 77b9f54b34e7989e6f402afb516f7ff2830df551c3a36973085e2c7a6b1045fe (include.zip)","title":"v3.7.1"},{"location":"home/releases/#summary_2","text":"This release fixes several small bugs in the library. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#bug-fixes_2","text":"Fixed a segmentation fault when serializing std::int64_t minimum value. #1708 #1722 Fixed the contains() function for JSON Pointers. #1727 #1741 Fixed too lax SFINAE guard for conversion from std::pair and std::tuple to json . #1805 #1806 #1825 #1826 Fixed some regressions detected by UBSAN. Updated CI to use Clang-Tidy 7.1.0. #1716 #1728 Fixed integer truncation in iteration_proxy . #1797 Updated Hedley to v11 to fix a E2512 error in MSVC. #1799 Fixed a compile error in enum deserialization of non non-default-constructible types. #1647 #1821 Fixed the conversion from json to std::valarray .","title":"Bug Fixes"},{"location":"home/releases/#improvements","text":"The items() function can now be used with a custom string type. #1765 Made json_pointer::back const . #1764 #1769 Meson is part of the release archive. #1672 #1694 Improved documentation on the Meson and Spack package manager. #1694 #1720","title":"Improvements"},{"location":"home/releases/#further-changes_1","text":"Added GitHub Workflow with ubuntu-latest /GCC 7.4.0 as CI step. Added GCC 9 to Travis CI to compile with C++20 support. #1724 Added MSVC 2019 to the AppVeyor CI. #1780 Added badge to fuzzing status . Fixed some cppcheck warnings. #1760 Fixed several typos in the documentation. #1720 #1767 #1803 Added documentation on the JSON_THROW_USER , JSON_TRY_USER , and JSON_CATCH_USER macros to control user-defined exception handling. Used GitHub's CODEOWNERS and SECURITY feature. Removed GLOB from CMake files. #1779 Updated to Doctest 2.3.5.","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_2","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v370","text":"Files include.zip (143 KB) include.zip.asc (1 KB) json.hpp (782 KB) json.hpp.asc (1 KB) Release date: 2019-07-28 SHA-256: a503214947952b69f0062f572cb74c17582a495767446347ce2e452963fc2ca4 (json.hpp), 541c34438fd54182e9cdc68dd20c898d766713ad6d901fb2c6e28ff1f1e7c10d (include.zip)","title":"v3.7.0"},{"location":"home/releases/#summary_3","text":"This release introduces a few convenience functions and performs a lot of house keeping (bug fixes and small improvements). All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#new-features","text":"Add overload of the contains function to check if a JSON pointer is valid without throwing exceptions, just like its counterpart for object keys . #1600 Add a function to_string to allow for generic conversion to strings. #916 #1585 Add return value for the emplace_back function , returning a reference to the added element just like C++17 is introducing this for std::vector . #1609 Add info how to use the library with the pacman package manager on MSYS2. #1670","title":"New Features"},{"location":"home/releases/#bug-fixes_3","text":"Fix an issue where typedefs with certain names yielded a compilation error. #1642 #1643 Fix a conversion to std::string_view in the unit tests. #1634 #1639 Fix MSVC Debug build. #1536 #1570 #1608 Fix get_to method to clear existing content before writing. #1511 #1555 Fix a -Wc++17-extensions warning. nodiscard attributes are now only used with Clang when -std=c++17 is used. #1535 #1551","title":"Bug Fixes"},{"location":"home/releases/#improvements_1","text":"Switch from Catch to doctest for the unit tests which speeds up compilation and runtime of the 112,112,308 tests. Add an explicit section to the README about the frequently addressed topics character encoding , comments in JSON , and the order of object keys .","title":"Improvements"},{"location":"home/releases/#further-changes_2","text":"Use GNUInstallDirs to set library install directories. #1673 Fix links in the README . #1620 #1621 #1622 #1623 #1625 Mention json type on the documentation start page . #1616 Complete documentation of value() function with respect to type_error.302 exception. #1601 Fix links in the documentation. #1598 Add regression tests for MSVC. #1543 #1570 Use CircleCI for continuous integration . Use Doozer for continuous integration on Linux (CentOS, Raspbian, Fedora) Add tests to check each CMake flag ( JSON_BuildTests , JSON_Install , JSON_MultipleHeaders , JSON_Sanitizer , JSON_Valgrind , JSON_NoExceptions , JSON_Coverage ). Use Hedley to avoid re-inventing several compiler-agnostic feature macros like JSON_DEPRECATED , JSON_NODISCARD , JSON_LIKELY , JSON_UNLIKELY , JSON_HAS_CPP_14 , or JSON_HAS_CPP_17 . Functions taking or returning pointers are annotated accordingly when a pointer will not be null. Build and run tests on AppVeyor in DEBUG and RELEASE mode.","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_3","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v361","text":"Files include.zip (136 KB) include.zip.asc (1 KB) json.hpp (711 KB) json.hpp.asc (1 KB) Release date: 2019-03-20 SHA-256: d2eeb25d2e95bffeb08ebb7704cdffd2e8fca7113eba9a0b38d60a5c391ea09a (json.hpp), 69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf (include.zip)","title":"v3.6.1"},{"location":"home/releases/#summary_4","text":"This release fixes a regression and a bug introduced by the earlier 3.6.0 release. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#bug-fixes_4","text":"Fixed regression of #590 which could lead to compilation errors with GCC 7 and GCC 8. #1530 Fixed a compilation error when was included. #1531","title":"Bug Fixes"},{"location":"home/releases/#further-changes_3","text":"Fixed a warning for missing field initializers. #1527","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_4","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v360","text":"Files include.zip (136 KB) include.zip.asc (1 KB) json.hpp (711 KB) json.hpp.asc (1 KB) Release date: 2019-03-20 SHA-256: ce9839370f28094c71107c405affb3b08c4a098154988014cbb0800b1c44a831 (json.hpp), 237c5e66e7f8186a02804ce9dbd5f69ce89fe7424ef84adf6142e973bd9532f4 (include.zip) \u2139\ufe0f This release introduced a regression. Please update to version 3.6.1 !","title":"v3.6.0"},{"location":"home/releases/#summary_5","text":"This release adds some convenience functions for JSON Pointers , introduces a contains function to check if a key is present in an object, and improves the performance of integer serialization . Furthermore, a lot of small bug fixes and improvements have been made. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#new-features_1","text":"Overworked the public interface for JSON Pointers. The creation of JSON Pointers is simplified with operator/ and operator/= . JSON Pointers can be inspected with empty , back , and parent_pointer , and manipulated with push_back and pop_back . #1434 Added a boolean method contains to check whether an element exists in a JSON object with a given key. Returns false when called on non-object types. #1471 #1474","title":"New Features"},{"location":"home/releases/#bug-fixes_5","text":"Fixed a compilation issues with libc 2.12. #1483 #1514 Fixed endian conversion on PPC64. #1489 Fixed library to compile with GCC 9. #1472 #1492 Fixed a compilation issue with GCC 7 on CentOS. #1496 Fixed an integer overflow. #1447 Fixed buffer flushing in serializer. #1445 #1446","title":"Bug Fixes"},{"location":"home/releases/#improvements_2","text":"The performance of dumping integers has been greatly improved. #1411 Added CMake parameter JSON_Install to control whether the library should be installed (default: on). #1330 Fixed a lot of compiler and linter warnings. #1400 #1435 #1502 Reduced required CMake version from 3.8 to 3.1. #1409 #1428 #1441 #1498 Added nodiscard attribute to meta() , array() , object() , from_cbor , from_msgpack , from_ubjson , from_bson , and parse . #1433","title":"Improvements"},{"location":"home/releases/#further-changes_4","text":"Added missing headers. #1500 Fixed typos and broken links in README. #1417 #1423 #1425 #1451 #1455 #1491 Fixed documentation of parse function. #1473 Suppressed warning that cannot be fixed inside the library. #1401 #1468 Imroved package manager suppert: Updated Buckaroo instructions. #1495 Improved Meson support. #1463 Added Conda package manager documentation. #1430 Added NuGet package manager documentation. #1132 Continuous Integration Removed unstable or deprecated Travis builders (Xcode 6.4 - 8.2) and added Xcode 10.1 builder. Added Clang 7 to Travis CI. Fixed AppVeyor x64 builds. #1374 #1414 Updated thirdparty libraries: Catch 1.12.0 -> 1.12.2 Google Benchmark 1.3.0 -> 1.4.1 Doxygen 1.8.15 -> 1.8.16","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_5","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v350","text":"Files include.zip (133 KB) include.zip.asc (1 KB) json.hpp (693 KB) json.hpp.asc (1 KB) Release date: 2018-12-22 SHA-256: 8a6dbf3bf01156f438d0ca7e78c2971bca50eec4ca6f0cf59adf3464c43bb9d5 (json.hpp), 3564da9c5b0cf2e032f97c69baedf10ddbc98030c337d0327a215ea72259ea21 (include.zip)","title":"v3.5.0"},{"location":"home/releases/#summary_6","text":"This release introduces the support for structured bindings and reading from FILE* . Besides, a few bugs have been fixed. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#new-features_2","text":"Structured bindings are now supported for JSON objects and arrays via the items() member function, so finally this code is possible: for ( auto & [ key , val ] : j . items ()) { std :: cout << key << ':' << val << '\\n' ; } #1388 #1391 Added support for reading from FILE* to support situations in which streams are nit available or would require too much RAM. #1370 #1392","title":"New Features"},{"location":"home/releases/#bug-fixes_6","text":"The eofbit was not set for input streams when the end of a stream was reached while parsing. #1340 #1343 Fixed a bug in the SAX parser for BSON arrays.","title":"Bug Fixes"},{"location":"home/releases/#improvements_3","text":"Added support for Clang 5.0.1 (PS4 version). #1341 #1342","title":"Improvements"},{"location":"home/releases/#further-changes_5","text":"Added a warning for implicit conversions to the documentation: It is not recommended to use implicit conversions when reading from a JSON value. Details about this recommendation can be found here . #1363 Fixed typos in the documentation. #1329 #1380 #1382 Fixed a C4800 warning. #1364 Fixed a -Wshadow warning #1346 Wrapped std::snprintf calls to avoid error in MSVC. #1337 Added code to allow installation via Meson. #1345","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_6","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v340","text":"Files include.zip (132 KB) include.zip.asc (1 KB) json.hpp (689 KB) json.hpp.asc (1 KB) Release date: 2018-10-30 SHA-256: 63da6d1f22b2a7bb9e4ff7d6b255cf691a161ff49532dcc45d398a53e295835f (json.hpp), bfec46fc0cee01c509cf064d2254517e7fa80d1e7647fea37cf81d97c5682bdc (include.zip)","title":"v3.4.0"},{"location":"home/releases/#summary_7","text":"This release introduces three new features: BSON (Binary JSON) is next to CBOR, MessagePack, and UBJSON the fourth binary (de)serialization format supported by the library. Adjustable error handlers for invalid Unicode allows to specify the behavior when invalid byte sequences are serialized. Simplified enum/JSON mapping with a macro in case the default mapping to integers is not desired. Furthermore, some effort has been invested in improving the parse error messages . Besides, a few bugs have been fixed. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#new-features_3","text":"The library can read and write a subset of BSON (Binary JSON) . All data types known from JSON are supported, whereas other types more tied to MongoDB such as timestamps, object ids, or binary data are currently not implemented. See the README for examples. #1244 #1320 The behavior when the library encounters an invalid Unicode sequence during serialization can now be controlled by defining one of three Unicode error handlers : (1) throw an exception (default behavior), (2) replace invalid sequences by the Unicode replacement character (U+FFFD), or (3) ignore/filter invalid sequences. See the documentation of the dump function for examples. #1198 #1314 To easily specify a user-defined enum/JSON mapping , a macro NLOHMANN_JSON_SERIALIZE_ENUM has been introduced. See the README section for more information. #1208 #1323","title":"New Features"},{"location":"home/releases/#bug-fixes_7","text":"fixed truncation #1286 #1315 fixed an issue with std::pair #1299 #1301 fixed an issue with std::variant #1292 #1294 fixed a bug in the JSON Pointer parser","title":"Bug Fixes"},{"location":"home/releases/#improvements_4","text":"The diagnosis messages for parse errors have been improved: error messages now indicated line/column positions where possible (in addition to a byte count) and also the context in which the error occurred (e.g., \"while parsing a JSON string\"). Example: error parse error at 2: syntax error - invalid string: control character must be escaped; last read: '' is now reported as 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 \\t; last read: '' . #1280 #1288 #1303","title":"Improvements"},{"location":"home/releases/#further-changes_6","text":"improved Meson documentation #1305 fixed some more linter warnings #1280 fixed Clang detection for third-party Google Benchmark library #1277","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_7","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v330","text":"Files include.zip (123 KB) include.zip.asc (1 KB) json.hpp (635 KB) json.hpp.asc (1 KB) Release date: 2018-10-05 SHA-256: f1327bb60c58757a3dd2b0c9c45d49503d571337681d950ec621f8374bcc14d4 (json.hpp), 9588d63557333aaa485e92221ec38014a85a6134e7486fe3441e0541a5a89576 (include.zip)","title":"v3.3.0"},{"location":"home/releases/#summary_8","text":"This release adds support for GCC 4.8 . Furthermore, it adds a function get_to to write a JSON value to a passed reference. Another topic of this release was the CMake support which has been overworked and documented. Besides, a lot of bugs have been fixed and slight improvements have been made. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#new-features_4","text":"The library can now also built with GCC 4.8 . Though this compiler does not fully support C++11, it can successfully compile and run the test suite. Note that bug 57824 in GCC 4.8 still forbids to use multiline raw strings in arguments to macros. #1257 Added new function get_to to write a JSON value to a passed reference. The destination type is automatically derived which allows more succinct code compared to the get function. #1227 #1231","title":"New Features"},{"location":"home/releases/#bug-fixes_8","text":"Fixed a bug in the CMake file that made target_link_libraries to not properly include nlohmann_json . #1243 #1245 #1260 Fixed a warning in MSVC 2017 complaining about a constexpr if. #1204 #1268 #1272 Fixed a bug that prevented compilation with ICPC. #755 #1222 Improved the SFINAE correctness to fix a bug in the conversion operator. #1237 #1238 Fixed a -Wctor-dtor-privacy warning. #1224 Fixed a warning on a lambda in unevaluated context. #1225 #1230 Fixed a bug introduced in version 3.2.0 where defining JSON_CATCH_USER led to duplicate macro definition of JSON_INTERNAL_CATCH . #1213 #1214 Fixed a bug that prevented compilation with Clang 3.4.2 in RHEL 7. #1179 #1249","title":"Bug Fixes"},{"location":"home/releases/#improvements_5","text":"Added documentation on CMake integration of the library. #1270 Changed the CMake file to use find_package(nlohmann_json) without installing the library. #1202 Improved error messages in case operator[] is used with the wrong combination (json.exception.type_error.305) of JSON container type and argument type. Example: \"cannot use operator[] with a string argument\". #1220 #1221 Added a license and version information to the Meson build file. #1252 Removed static assertions to indicated missing to_json or from_json functions as such assertions do not play well with SFINAE. These assertions also led to problems with GMock. #960 #1212 #1228 The test suite now does not wait forever if run in a wrong directory and input files are not found. #1262 The test suite does not show deprecation warnings for deprecated functions which frequently led to confusion. #1271","title":"Improvements"},{"location":"home/releases/#further-changes_7","text":"GCC 4.8 and Xcode 10 were added to the continuous integration suite at Travis. Added lgtm checks to pull requests. Added tests for CMake integration. #1260","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_8","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v320","text":"Files include.zip (124 KB) include.zip.asc (1 KB) json.hpp (636 KB) json.hpp.asc (1 KB) Release date: 2018-08-20 SHA-256: ce6b5610a051ec6795fa11c33854abebb086f0fd67c311f5921c3c07f9531b44 (json.hpp), 35ee642558b90e2f9bc758995c4788c4b4d4dec54eef95fb8f38cb4d49c8fc7c (include.zip)","title":"v3.2.0"},{"location":"home/releases/#summary_9","text":"This release introduces a SAX interface to the library. While this may be a very special feature used by only few people, it allowed to unify all functions that consumed input and created some kind of JSON value. Internally, now all existing functions like parse , accept , from_cbor , from_msgpack , and from_ubjson use the SAX interface with different event processors. This allowed to separate the input processing from the value generation. Furthermore, throwing an exception in case of a parse error is now optional and up to the event processor. Finally, the JSON parser is now non-recursive (meaning it does not use the call stack, but std::vector to track the hierarchy of structured values) which allows to process nested input more efficiently. Furthermore, the library finally is able to parse from wide string types . This is the first step toward opening the library from UTF-8 to UTF-16 and UTF-32. This release further fixes several bugs in the library. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#new-features_5","text":"added a parser with a SAX interface (#971, #1153) support to parse from wide string types std::wstring , std::u16string , and std::u32string ; the input will be converted to UTF-8 (#1031) added support for std::string_view when using C++17 (#1028) allow to roundtrip std::map and std::unordered_map from JSON if key type is not convertible to string; in these cases, values are serialized to arrays of pairs (#1079, #1089, #1133, #1138)","title":"New Features"},{"location":"home/releases/#bug-fixes_9","text":"allow to create nullptr_t from JSON allowing to properly roundtrip null values (#1169) allow compare user-defined string types (#1130) better support for algorithms using iterators from items() (#1045, #1134) added parameter to avoid compilation error with MSVC 2015 debug builds (#1114) re-added accidentally skipped unit tests (#1176) fixed MSVC issue with std::swap (#1168)","title":"Bug Fixes"},{"location":"home/releases/#improvements_6","text":"key() function for iterators returns a const reference rather than a string copy (#1098) binary formats CBOR, MessagePack, and UBJSON now supports float as type for floating-point numbers (#1021)","title":"Improvements"},{"location":"home/releases/#further-changes_8","text":"changed issue templates improved continuous integration: added builders for Xcode 9.3 and 9.4, added builders for GCC 8 and Clang 6, added builder for MinGW, added builders for MSVC targeting x86 required CMake version is now at least 3.8 (#1040) overworked CMake file wrt. packaging (#1048) added package managers: Spack (#1041) and CocoaPods (#1148) fixed Meson include directory (#1142) preprocessor macro JSON_SKIP_UNSUPPORTED_COMPILER_CHECK can skip the rejection of unsupported compilers - use at your own risk! (#1128) preprocessor macro JSON_INTERNAL_CATCH / JSON_INTERNAL_CATCH_USER allows to control the behavior of exception handling inside the library (#1187) added note on char to JSON conversion added note how to send security-related issue via encrypted email removed dependency to std::stringstream (#1117) added SPDX-License-Identifier added updated JSON Parsing Test Suite, described in Parsing JSON is a Minefield \ud83d\udca3 updated to Catch 1.12.0","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_9","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v312","text":"Files include.zip (115 KB) include.zip.asc (1 KB) json.hpp (582 KB) json.hpp.asc (1 KB) Release date: 2018-03-14 SHA-256: fbdfec4b4cf63b3b565d09f87e6c3c183bdd45c5be1864d3fcb338f6f02c1733 (json.hpp), 495362ee1b9d03d9526ba9ccf1b4a9c37691abe3a642ddbced13e5778c16660c (include.zip)","title":"v3.1.2"},{"location":"home/releases/#summary_10","text":"This release fixes several bugs in the library. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#bug-fixes_10","text":"Fixed a memory leak occurring in the parser callback (#1001). Different specializations of basic_json (e.g., using different template arguments for strings or objects) can now be used in assignments (#972, #977, #986). Fixed a logical error in an iterator range check (#992).","title":"Bug Fixes"},{"location":"home/releases/#improvements_7","text":"The parser and the serialization now support user-defined string types (#1006, #1009).","title":"Improvements"},{"location":"home/releases/#further-changes_9","text":"Clang Analyzer is now used as additional static analyzer; see make clang_analyze . Overworked README by adding links to the documentation (#981).","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_10","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v311","text":"Files include.zip (114 KB) include.zip.asc (1 KB) json.hpp (577 KB) json.hpp.asc (1 KB) Release date: 2018-02-13 SHA-256: e14ce5e33d6a2daf748026bd4947f3d9686ca4cfd53d10c3da46a0a9aceb7f2e (json.hpp), fde771d4b9e4f222965c00758a2bdd627d04fb7b59e09b7f3d1965abdc848505 (include.zip)","title":"v3.1.1"},{"location":"home/releases/#summary_11","text":"This release fixes several bugs in the library. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#bug-fixes_11","text":"Fixed parsing of CBOR strings with indefinite length (#961). Earlier versions of this library misinterpreted the CBOR standard and rejected input with the 0x7F start byte. Fixed user-defined conversion to vector type (#924, #969). A wrong SFINAE check rejected code though a user-defined conversion was provided. Fixed documentation of the parser behavior for objects with duplicate keys (#963). The exact behavior is not specified by RFC 8259 and the library now also provides no guarantee which object key is stored. Added check to detect memory overflow when parsing UBJSON containers (#962). The optimized UBJSON format allowed for specifying an array with billions of null elements with a few bytes and the library did not check whether this size exceeded max_size() .","title":"Bug Fixes"},{"location":"home/releases/#further-changes_10","text":"Code coverage is now calculated for the individual header files, allowing to find uncovered lines more quickly than by browsing through the single header version (#953, #957). A Makefile target run_benchmarks was added to quickly build and run the benchmark suite. The documentation was harmonized with respect to the header inclusion (#955). Now all examples and the README use #include to allow for selecting single_include or include or whatever installation folder as include directory. Added note on how to use the library with the cget package manager (#954).","title":"Further Changes"},{"location":"home/releases/#deprecated-functions_11","text":"This release does not deprecate any functions. As an overview, the following functions have been deprecated in earlier versions and will be removed in the next major version (i.e., 4.0.0): Function iterator_wrapper are deprecated. Please use the member function items() instead. Functions friend std::istream& operator<<(basic_json&, std::istream&) and friend std::ostream& operator>>(const basic_json&, std::ostream&) are deprecated. Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v310","text":"Files include.zip (114 KB) include.zip.asc (1 KB) json.hpp (577 KB) json.hpp.asc (1 KB) Release date: 2018-02-01 SHA-256: d40f614d10a6e4e4e80dca9463da905285f20e93116c36d97d4dc1aa63d10ba4 (json.hpp), 2b7234fca394d1e27b7e017117ed80b7518fafbb4f4c13a7c069624f6f924673 (include.zip)","title":"v3.1.0"},{"location":"home/releases/#summary_12","text":"This release adds support for the UBJSON format and JSON Merge Patch . It also contains some minor changes and bug fixes. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#new-features_6","text":"The library now supports UBJSON (Universal Binary JSON Specification) as binary format to read and write JSON values space-efficiently. See the documentation overview for a comparison of the different formats CBOR, MessagePack, and UBJSON. JSON Merge Patch (RFC 7386) offers an intuitive means to describe patches between JSON values (#876, #877). See the documentation of merge_patch for more information.","title":"New features"},{"location":"home/releases/#improvements_8","text":"The library now uses the Grisu2 algorithm for printing floating-point numbers (based on the reference implementation by Florian Loitsch) which produces a short representation which is guaranteed to round-trip (#360, #935, #936). The UTF-8 handling was further simplified by using the decoder of Bj\u00f6rn Hoehrmann in more scenarios.","title":"Improvements"},{"location":"home/releases/#reorganization","text":"Though the library is released as a single header, its development got more and more complicated. With this release, the header is split into several files and the single-header file json.hpp can be generated from these development sources. In the repository, folder include contains the development sources and single_include contains the single json.hpp header (#700, #906, #907, #910, #911, #915, #920, #924, #925, #928, #944). The split further allowed for a forward declaration header include/nlohmann/json_fwd.hpp to speed up compilation times (#314).","title":"Reorganization"},{"location":"home/releases/#further-changes_11","text":"Google Benchmark is now used for micro benchmarks (see benchmarks folder, #921). The serialization (JSON and binary formats) now properly work with the libraries string template parameter, allowing for optimized string implementations to be used in constraint environments such as embedded software (#941, #950). The exceptional behavior can now be overridden by defining macros JSON_THROW_USER , JSON_TRY_USER , and JSON_CATCH_USER , defining the behavior of throw , try and catch , respectively. This allows to switch off C++'s exception mechanism yet still execute user-defined code in case an error condition occurs (#938). To facilitate the interplay with flex and Bison , the library does not use the variable name yytext any more as it could clash with macro definitions (#933). The library now defines NLOHMANN_JSON_VERSION_MAJOR , NLOHMANN_JSON_VERSION_MINOR , and NLOHMANN_JSON_VERSION_PATCH to allow for conditional compilation based on the included library version (#943, #948). A compilation error with ICC has been fixed (#947). Typos and links in the documentation have been fixed (#900, #930). A compiler error related to incomplete types has been fixed (#919). The tests form the UTF-8 decoder stress test have been added to the test suite.","title":"Further changes"},{"location":"home/releases/#deprecated-functions_12","text":"Function iterator_wrapper has been deprecated (#874). Since its introduction, the name was up for discussion, as it was too technical. We now introduced the member function items() with the same semantics. iterator_wrapper will be removed in the next major version (i.e., 4.0.0). Furthermore, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0): friend std::istream& operator<<(basic_json&, std::istream&) friend std::ostream& operator>>(const basic_json&, std::ostream&) Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v301","text":"Files json.hpp (502 KB) json.hpp.asc (1 KB) Release date: 2017-12-29 SHA-256: c9b3591f1bb94e723a0cd7be861733a3a555b234ef132be1e9027a0364118c4c","title":"v3.0.1"},{"location":"home/releases/#summary_13","text":"This release fixes small issues in the implementation of JSON Pointer and JSON Patch . All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#changes","text":"The \"copy\" operation of JSON Patch ( RFC 6902 ) requests that it is an error if the target path points into a non-existing array or object (see #894 for a detailed description). This release fixes the implementation to detect such invalid target paths and throw an exception. An array index in a JSON Pointer ( RFC 6901 ) must be an integer. This release fixes the implementation to throw an exception in case invalid array indices such as 10e2 are used. Added the JSON Patch tests from Byron Ruth and Mike McCabe. Fixed the documentation of the at(ptr) function with JSON Pointers to list all possible exceptions (see #888). Updated the container overview documentation (see #883). The CMake files now respect the BUILD_TESTING option (see #846, #885) Fixed some compiler warnings (see #858, #882).","title":"Changes"},{"location":"home/releases/#deprecated-functions_13","text":"To unify the interfaces and to improve similarity with the STL, the following functions are deprecated since version 3.0.0 and will be removed in the next major version (i.e., 4.0.0): friend std::istream& operator<<(basic_json&, std::istream&) friend std::ostream& operator>>(const basic_json&, std::ostream&) Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#v300","text":"Files json.hpp (501 KB) json.hpp.asc (1 KB) Release date: 2017-12-17 SHA-256: 076d4a0cb890a3c3d389c68421a11c3d77c64bd788e85d50f1b77ed252f2a462","title":"v3.0.0"},{"location":"home/releases/#summary_14","text":"After almost a year, here is finally a new release of JSON for Modern C++, and it is a major one! As we adhere to semantic versioning , this means the release includes some breaking changes, so please read the next section carefully before you update. But don't worry, we also added a few new features and put a lot of effort into fixing a lot of bugs and straighten out a few inconsistencies.","title":"Summary"},{"location":"home/releases/#breaking-changes","text":"This section describes changes that change the public API of the library and may require changes in code using a previous version of the library. In section \"Moving from 2.x.x to 3.0.0\" at the end of the release notes, we describe in detail how existing code needs to be changed. The library now uses user-defined exceptions instead of re-using those defined in (#244). This not only allows to add more information to the exceptions (every exception now has an identifier, and parse errors contain the position of the error), but also to easily catch all library exceptions with a single catch(json::exception) . When strings with a different encoding as UTF-8 were stored in JSON values, their serialization could not be parsed by the library itself, as only UTF-8 is supported. To enforce this library limitation and improve consistency, non-UTF-8 encoded strings now yield a json::type_error exception during serialization (#838). The check for valid UTF-8 is realized with code from Bj\u00f6rn Hoehrmann . NaN and infinity values can now be stored inside the JSON value without throwing an exception. They are, however, still serialized as null (#388). The library's iterator tag was changed from RandomAccessIterator to BidirectionalIterator (#593). Supporting RandomAccessIterator was incorrect as it assumed an ordering of values in a JSON objects which are unordered by definition. The library does not include the standard headers , , and any more. You may need to add these headers to code relying on them. Removed constructor explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr) which was deprecated in version 2.0.0 (#480).","title":"Breaking changes"},{"location":"home/releases/#deprecated-functions_14","text":"To unify the interfaces and to improve similarity with the STL, the following functions are now deprecated and will be removed in the next major version (i.e., 4.0.0): friend std::istream& operator<<(basic_json&, std::istream&) friend std::ostream& operator>>(const basic_json&, std::ostream&) Please use friend std::istream& operator>>(std::istream&, basic_json&) and friend operator<<(std::ostream&, const basic_json&) instead.","title":"Deprecated functions"},{"location":"home/releases/#new-features_7","text":"With all this breaking and deprecation out of the way, let's talk about features! We improved the diagnostic information for syntax errors (#301). Now, an exception json::parse_error is thrown which contains a detailed message on the error, but also a member byte to indicate the byte offset in the input where the error occurred. We added a non-throwing syntax check (#458): The new accept function returns a Boolean indicating whether the input is proper JSON. We also added a Boolean parameter allow_exceptions to the existing parse functions to return a discarded value in case a syntax error occurs instead of throwing an exception. An update function was added to merge two JSON objects (#428). In case you are wondering: the name was inspired by Python . The insert function now also supports an iterator range to add elements to an object. The binary exchange formats CBOR and MessagePack can now be parsed from input streams and written to output streams (#477). Input streams are now only read until the end of a JSON value instead of the end of the input (#367). The serialization function dump now has two optional parameters ensure_ascii to escape all non-ASCII characters with \\uxxxx and an indent_char parameter to choose whether to indent with spaces or tabs (#654). Added built-in type support for C arrays (#502), std::pair and std::tuple (#563, #614), enum and enum class (#545), std::vector (#494). Fixed support for std::valarray (#702), std::array (#553), and std::map (#600, #607).","title":"New features"},{"location":"home/releases/#further-changes_12","text":"Furthermore, there have been a lot of changes under the hood: Replaced the re2c generated scanner by a self-coded version which allows for a better modularization of the parser and better diagnostics. To test the new scanner, we added millions (8,860,608 to be exact) of unit tests to check all valid and invalid byte sequences of the Unicode standard. Google's OSS-Fuzz is still constantly fuzz-testing the library and found several issues that were fixed in this release (#497, #504, #514, #516, #518, #519, #575). We now also ignore UTF-8 byte order marks when parsing from an iterator range (#602). Values can be now moved from initializer lists (#663). Updated to Catch 1.9.7. Unfortunately, Catch2 currently has some performance issues. The non-exceptional paths of the library are now annotated with __builtin_expect to optimize branch prediction as long as no error occurs. MSVC now produces a stack trace in MSVC if a from_json or to_json function was not found for a user-defined type. We also added a debug visualizer nlohmann_json.natvis for better debugging in MSVC (#844). Overworked the documentation and added even more examples. The build workflow now relies on CMake and CTest. Special flags can be chosen with CMake, including coverage ( JSON_Coverage ), compilation without exceptions ( JSON_NoExceptions ), LLVM sanitizers ( JSON_Sanitizer ), or execution with Valgrind ( JSON_Valgrind ). Added support for package managers Meson (#576), Conan (#566), Hunter (#671, #829), and vcpkg (#753). Added CI builders: Xcode 8.3, 9.0, 9.1, and 9.2; GCC 7.2; Clang 3.8, 3.9, 4.0, and 5.0; Visual Studio 2017. The library is further built with C++17 settings on the latest Clang, GCC, and MSVC version to quickly detect new issues.","title":"Further changes"},{"location":"home/releases/#moving-from-2xx-to-300","text":"","title":"Moving from 2.x.x to 3.0.0"},{"location":"home/releases/#user-defined-exceptions","text":"There are five different exceptions inheriting from json::exception : json::parse_error for syntax errors (including the binary formats), json::invalid_iterator for errors related to iterators, json::type_error for errors where functions were called with the wrong JSON type, json::out_of_range for range errors, and json::other_error for miscellaneous errors. To support these exception, the try / catch blocks of your code need to be adjusted: new exception previous exception parse_error.101 invalid_argument parse_error.102 invalid_argument parse_error.103 invalid_argument parse_error.104 invalid_argument parse_error.105 invalid_argument parse_error.106 domain_error parse_error.107 domain_error parse_error.108 domain_error parse_error.109 invalid_argument parse_error.110 out_of_range parse_error.111 invalid_argument parse_error.112 invalid_argument invalid_iterator.201 domain_error invalid_iterator.202 domain_error invalid_iterator.203 domain_error invalid_iterator.204 out_of_range invalid_iterator.205 out_of_range invalid_iterator.206 domain_error invalid_iterator.207 domain_error invalid_iterator.208 domain_error invalid_iterator.209 domain_error invalid_iterator.210 domain_error invalid_iterator.211 domain_error invalid_iterator.212 domain_error invalid_iterator.213 domain_error invalid_iterator.214 out_of_range type_error.301 domain_error type_error.302 domain_error type_error.303 domain_error type_error.304 domain_error type_error.305 domain_error type_error.306 domain_error type_error.307 domain_error type_error.308 domain_error type_error.309 domain_error type_error.310 domain_error type_error.311 domain_error type_error.313 domain_error type_error.314 domain_error type_error.315 domain_error out_of_range.401 out_of_range out_of_range.402 out_of_range out_of_range.403 out_of_range out_of_range.404 out_of_range out_of_range.405 domain_error other_error.501 domain_error","title":"User-defined Exceptions"},{"location":"home/releases/#handling-of-nan-and-inf","text":"If an overflow occurs during parsing a number from a JSON text, an exception json::out_of_range is thrown so that the overflow is detected early and roundtripping is guaranteed. NaN and INF floating-point values can be stored in a JSON value and are not replaced by null. That is, the basic_json class behaves like double in this regard (no exception occurs). However, NaN and INF are serialized to null .","title":"Handling of NaN and INF"},{"location":"home/releases/#removal-of-deprecated-functions","text":"Function explicit basic_json(std::istream& i, const parser_callback_t cb = nullptr) should be replaced by the parse function: Let ss be a stream and cb be a parse callback function. Old code: json j ( ss , cb ); New code: json j = json :: parse ( ss , cb ); If no callback function is used, also the following code works: json j ; j << ss ; or json j ; ss >> j ;","title":"Removal of deprecated functions"},{"location":"home/releases/#v211","text":"Files json.hpp (437 KB) json.hpp.asc (1 KB) Release date: 2017-02-25 SHA-256: faa2321beb1aa7416d035e7417fcfa59692ac3d8c202728f9bcc302e2d558f57","title":"v2.1.1"},{"location":"home/releases/#summary_15","text":"This release fixes a locale-related bug in the parser . To do so, the whole number handling (lexer, parser, and also the serialization) have been overworked. Furthermore, a lot of small changes added up that were added to this release. All changes are backward-compatible.","title":"Summary"},{"location":"home/releases/#changes_1","text":"Locales that have a different character than . as decimal separator (e.g., the Norwegian locale nb_NO.UTF-8 ) led to truncated number parsing or parse errors. The library now has been fixed to work with any locale . Note that . is still the only valid decimal separator for JSON input. Numbers like 1.0 were correctly parsed as floating-point number, but serialized as integer ( 1 ). Now, floating-point numbers correctly round trip . Parsing incorrect JSON numbers with leading 0 ( 0123 ) could yield a buffer overflow . This is fixed now by detecting such errors directly by the lexer. Constructing a JSON value from a pointer was incorrectly interpreted as a Boolean; such code will now yield a compiler error. Comparing a JSON number with 0 led to a comparison with null . This is fixed now. All throw calls are now wrapped in macros. Starting during the preparation of this release (since 8 February 2017), commits and released files are cryptographically signed with this GPG key . Previous releases have also been signed. The parser for MessagePack and CBOR now supports an optional start index parameter to define a byte offset for the parser. Some more warnings have been fixed. With Clang, the code compiles without warnings with -Weverything (well, it needs -Wno-documentation-unknown-command and -Wno-deprecated-declarations , but you get the point). The code can be compiled easier with many Android NDKs by avoiding macros like UINT8_MAX which previously required defining a preprocessor macro for compilation. The unit tests now compile two times faster. Cotire is used to speed up the build. Fixed a lot of typos in the documentation. Added a section to the README file that lists all used third-party code/tools . Added a note on constructing a string value vs. parsing. The test suite now contains 11202597 unit tests. Improved the Doxygen documentation by shortening the template parameters of class basic_json . Removed Doozer. Added Codacity. Upgraded Catch to version 1.7.2.","title":"Changes"},{"location":"home/releases/#v210","text":"Files json.hpp (426 KB) json.hpp.asc (1 KB) Release date: 2017-01-28 SHA-256: a571dee92515b685784fd527e38405cf3f5e13e96edbfe3f03d6df2e363a767b","title":"v2.1.0"},{"location":"home/releases/#summary_16","text":"This release introduces a means to convert from/to user-defined types. The release is backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_2","text":"The library now offers an elegant way to convert from and to arbitrary value types . All you need to do is to implement two functions: to_json and from_json . Then, a conversion is as simple as putting a = between variables. See the README for more information and examples. Exceptions can now be switched off. This can be done by defining the preprocessor symbol JSON_NOEXCEPTION or by passing -fno-exceptions to your compiler. In case the code would usually thrown an exception, abort() is now called. Information on the library can be queried with the new (static) function meta() which returns a JSON object with information on the version, compiler, and platform. See the documentation for an example. A bug in the CBOR parser was fixed which led to a buffer overflow. The function type_name() is now public. It allows to query the type of a JSON value as string. Added the Big List of Naughty Strings as test case. Updated to Catch v1.6.0 . Some typos in the documentation have been fixed.","title":"Changes"},{"location":"home/releases/#v2010","text":"Files json.hpp (409 KB) json.hpp.asc (1 KB) Release date: 2017-01-02 SHA-256: ec27d4e74e9ce0f78066389a70724afd07f10761009322dc020656704ad5296d","title":"v2.0.10"},{"location":"home/releases/#summary_17","text":"This release fixes several security-relevant bugs in the MessagePack and CBOR parsers. The fixes are backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_3","text":"Fixed a lot of bugs in the CBOR and MesssagePack parsers . These bugs occurred if invalid input was parsed and then could lead in buffer overflows. These bugs were found with Google's OSS-Fuzz , see #405, #407, #408, #409, #411, and #412 for more information. We now also use the Doozer continuous integration platform . The complete test suite is now also run with Clang's address sanitizer and undefined-behavior sanitizer . Overworked fuzz testing ; CBOR and MessagePack implementations are now fuzz-tested. Furthermore, all fuzz tests now include a round trip which ensures created output can again be properly parsed and yields the same JSON value. Clarified documentation of find() function to always return end() when called on non-object value types. Moved thirdparty test code to test/thirdparty directory.","title":"Changes"},{"location":"home/releases/#v209","text":"Files json.hpp (406 KB) json.hpp.asc (1 KB) Release date: 2016-12-16 SHA-256: fbf3396f13e187d6c214c297bddc742d918ea9b55e10bfb3d9f458b9bfdc22e5","title":"v2.0.9"},{"location":"home/releases/#summary_18","text":"This release implements with CBOR and MessagePack two binary serialization/deserialization formats . It further contains some small fixes and improvements. The fixes are backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_4","text":"The library can now read and write the binary formats CBOR (Concise Binary Object Representation) and MessagePack . Both formats are aimed to produce a very compact representation of JSON which can be parsed very efficiently. See the README file for more information and examples. simplified the iteration implementation allowing to remove dozens of lines of code fixed an integer overflow error detected by Google's OSS-Fuzz suppressed documentation warnings inside the library to facilitate compilation with -Wdocumentation fixed an overflow detection error in the number parser updated contribution guidelines to a list of frequentely asked features that will most likely be never added to the library added a table of contents to the README file to add some structure mentioned the many examples and the documentation in the README file split unit tests into individual independent binaries to speed up compilation and testing the test suite now contains 11201886 tests","title":"Changes"},{"location":"home/releases/#v208","text":"Files json.hpp (360 KB) json.hpp.asc (1 KB) Release date: 2016-12-02 SHA-256: b70db0ad34f8e0e61dc3f0cbab88099336c9674c193d8a3439d93d6aca2d7120","title":"v2.0.8"},{"location":"home/releases/#summary_19","text":"This release combines a lot of small fixes and improvements. The fixes are backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_5","text":"fixed a bug that froze the parser if a passed file was not found (now, std::invalid_argument is thrown) fixed a bug that lead to an error of a file at EOF was parsed again (now, std::invalid_argument is thrown) the well known functions emplace and emplace_back have been added to JSON values and work as expected improved the performance of the serialization ( dump function) improved the performance of the deserialization (parser) some continuous integration images at Travis were added and retired; see here for the current continuous integration setup the Coverity scan works again the benchmarking code has been improved to produce more stable results the README file has been extended and includes more frequently asked examples the test suite now contains 8905518 tests updated Catch to version 1.5.8","title":"Changes"},{"location":"home/releases/#v207","text":"Files json.hpp (355 KB) json.hpp.asc (1 KB) Release date: 2016-11-02 SHA-256: 5545c323670f8165bae90b9dc6078825e86ec310d96cc4e5b47233ea43715bbf","title":"v2.0.7"},{"location":"home/releases/#summary_20","text":"This release fixes a few bugs in the JSON parser found in the Parsing JSON is a Minefield \ud83d\udca3 article. The fixes are backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_6","text":"The article Parsing JSON is a Minefield \ud83d\udca3 discusses a lot of pitfalls of the JSON specification. When investigating the published test cases, a few bugs in the library were found and fixed: Files with less than 5 bytes can now be parsed without error. The library now properly rejects any file encoding other than UTF-8. Furthermore, incorrect surrogate pairs are properly detected and rejected. The library now accepts all but one \"yes\" test (y_string_utf16.json): UTF-16 is not supported. The library rejects all but one \"no\" test (n_number_then_00.json): Null bytes are treated as end of file instead of an error. This allows to parse input from null-terminated strings. The string length passed to a user-defined string literal is now exploited to choose a more efficient constructor. A few grammar mistakes in the README file have been fixed.","title":"Changes"},{"location":"home/releases/#v206","text":"Files json.hpp (349 KB) json.hpp.asc (1 KB) Release date: 2016-10-15 SHA256: 459cc93d5e2f503e50c6d5876eb86bfea7daf405f5a567c5a2c9abc2383756ae","title":"v2.0.6"},{"location":"home/releases/#summary_21","text":"This release fixes the semantics of operator[] for JSON Pointers (see below). This fix is backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_7","text":"operator[] for JSON Pointers now behaves like the other versions of operator[] and transforms null values into objects or arrays if required. This allows to created nested structures like j[\"/foo/bar/2\"] = 17 (yielding {\"foo\": \"bar\": [null, null, 17]} ) without problems. overworked a helper SFINAE function fixed some documentation issues fixed the CMake files to allow to run the test suite outside the main project directory restored test coverage to 100%.","title":"Changes"},{"location":"home/releases/#v205","text":"Files json.hpp (347 KB) json.hpp.asc (1 KB) Release date: 2016-09-14 SHA-256: 8b7565263a44e2b7d3b89808bc73d2d639037ff0c1f379e3d56dbd77e00b98d9","title":"v2.0.5"},{"location":"home/releases/#summary_22","text":"This release fixes a regression bug in the stream parser (function parse() and the << / >> operators). This fix is backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_8","text":"Bug fix : The end of a file stream was not detected properly which led to parse errors. This bug should have been fixed with 2.0.4, but there was still a flaw in the code.","title":"Changes"},{"location":"home/releases/#v204","text":"Files json.hpp (347 KB) json.hpp.asc (1 KB) Release date: 2016-09-11 SHA-256: 632ceec4c25c4e2153f71470d3a2b992c8355f6d8b4d627d05dd16095cd3aeda","title":"v2.0.4"},{"location":"home/releases/#summary_23","text":"This release fixes a bug in the stream parser (function parse() and the << / >> operators). This fix is backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_9","text":"Bug fix : The end of a file stream was not detected properly which led to parse errors. Fixed a compiler warning about an unused variable.","title":"Changes"},{"location":"home/releases/#v203","text":"Files json.hpp (347 KB) json.hpp.asc (1 KB) Release date: 2016-08-31 SHA-256: 535b73efe5546fde9e763c14aeadfc7b58183c0b3cd43c29741025aba6cf6bd3","title":"v2.0.3"},{"location":"home/releases/#summary_24","text":"This release combines a lot of small fixes and improvements. The release is backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_10","text":"The parser/deserialization functions have been generalized to process any contiguous sequence of 1-byte elements (e.g., char , unsigned char , uint8_t ). This includes all kind of string representations (string literals, char arrays, std::string , const char* ), contiguous containers (C-style arrays, std::vector , std::array , std::valarray , std::initializer_list ). User-defined containers providing random-access iterator access via std::begin and std::end can be used as well. See the documentation ( 1 , 2 , 3 , 4 ) for more information. Note that contiguous storage cannot be checked at compile time; if any of the parse functions are called with a noncompliant container, the behavior is undefined and will most likely yield segmentation violation. The preconditions are enforced by an assertion unless the library is compiled with preprocessor symbol NDEBUG . As a general remark on assertions : The library uses assertions to preclude undefined behavior. A prominent example for this is the operator[] for const JSON objects. The behavior of this const version of the operator is undefined if the given key does not exist in the JSON object, because unlike the non-const version, it cannot add a null value at the given key. Assertions can be switched of by defining the preprocessor symbol NDEBUG . See the documentation of assert for more information. In the course of cleaning up the parser/deserialization functions, the constructor basic_json(std::istream&, const parser_callback_t) has been deprecated and will be deleted with the next major release 3.0.0 to unify the interface of the library. Deserialization will be done by stream operators or by calling one of the parse functions. That is, calls like json j(i); for an input stream i need to be replaced by json j = json::parse(i); . Compilers will produce a deprecation warning if client code uses this function. Minor improvements: Improved the performance of the serialization by avoiding the re-creation of a locale object. Fixed two MSVC warnings. Compiling the test suite with /Wall now only warns about non-inlined functions (C4710) and the deprecation of the constructor from input-stream (C4996). Some project internals: The project has qualified for the Core Infrastructure Initiative Best Practices Badge . While most requirements where already satisfied, some led to a more explicit documentation of quality-ensuring procedures. For instance, static analysis is now executed with every commit on the build server. Furthermore, the contribution guidelines document how to communicate security issues privately. The test suite has been overworked and split into several files to allow for faster compilation and analysis. The execute the test suite, simply execute make check . The continuous integration with Travis was extended with Clang versions 3.6.0 to 3.8.1 and now includes 18 different compiler/OS combinations. An 11-day run of American fuzzy lop checked 962 million inputs on the parser and found no issue.","title":"Changes"},{"location":"home/releases/#v202","text":"Files json.hpp (338 KB) json.hpp.asc (1 KB) Release date: 2016-07-31 SHA-256: 8e97b7965b4594b00998d6704465412360e1a0ed927badb51ded8b82291a8f3d","title":"v2.0.2"},{"location":"home/releases/#summary_25","text":"This release combines a lot of small fixes and improvements. The release is backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_11","text":"The parser has been overworked, and a lot of small issues have been fixed: Improved parser performance by avoiding recursion and using move semantics for the return value. Unescaped control characters \\x10 - \\x1f are not accepted any more. Fixed a bug in the parser when reading from an input stream. Improved test case coverage for UTF-8 parsing: now, all valid Unicode code points are tested both escaped and unescaped. The precision of output streams is now preserved by the parser. Started to check the code correctness by proving termination of important loops. Furthermore, individual assertions have been replaced by a more systematic function which checks the class invariants. Note that assertions should be switched off in production by defining the preprocessor macro NDEBUG , see the documentation of assert . A lot of code cleanup : removed unused headers, fixed some compiler warnings, and fixed a build error for Windows-based Clang builds. Added some compile-time checks: Unsupported compilers are rejected during compilation with an #error command. Static assertion prohibits code with incompatible pointer types used in get_ptr() . Improved the documentation , and adjusted the documentation script to choose the correct version of sed . Replaced a lot of \"raw loops\" by STL functions like std::all_of , std::for_each , or std::accumulate . This facilitates reasoning about termination of loops and sometimes allowed to simplify functions to a single return statement. Implemented a value() function for JSON pointers (similar to at function). The Homebrew formula (see Integration ) is now tested for all Xcode builds (6.1 - 8.x) with Travis. Avoided output to std::cout in the test cases.","title":"Changes"},{"location":"home/releases/#v201","text":"Files json.hpp (321 KB) json.hpp.asc (1 KB) Release date: 2016-06-28 SHA-256: ef550fcd7df572555bf068e9ec4e9d3b9e4cdd441cecb0dcea9ea7fd313f72dd","title":"v2.0.1"},{"location":"home/releases/#summary_26","text":"This release fixes a performance regression in the JSON serialization (function dump() ). This fix is backwards compatible.","title":"Summary"},{"location":"home/releases/#changes_12","text":"The locale of the output stream (or the internal string stream if a JSON value is serialized to a string) is now adjusted once for the whole serialization instead of for each floating-point number. The locale of an output stream is now correctly reset to the previous value by the JSON library.","title":"Changes"},{"location":"home/releases/#v200","text":"Files json.hpp (321 KB) json.hpp.asc (1 KB) Release date: 2016-06-24 SHA-256: ac9e1fb25c2ac9ca5fc501fcd2fe3281fe04f07018a1b48820e7b1b11491bb6c","title":"v2.0.0"},{"location":"home/releases/#summary_27","text":"This release adds several features such as JSON Pointers, JSON Patch, or support for 64 bit unsigned integers. Furthermore, several (subtle) bugs have been fixed. As noexcept and constexpr specifier have been added to several functions, the public API has effectively been changed in a (potential) non-backwards compatible manner. As we adhere to Semantic Versioning , this calls for a new major version, so say hello to 2\ufe0f\u20e3.0\ufe0f\u20e3.0\ufe0f\u20e3.","title":"Summary"},{"location":"home/releases/#changes_13","text":"\ud83d\udd1f A JSON value now uses uint64_t (default value for template parameter NumberUnsignedType ) as data type for unsigned integer values. This type is used automatically when an unsigned number is parsed. Furthermore, constructors, conversion operators and an is_number_unsigned() test have been added. \ud83d\udc49 JSON Pointer ( RFC 6901 ) support: A JSON Pointer is a string (similar to an XPath expression) to address a value inside a structured JSON value. JSON Pointers can be used in at() and operator[] functions. Furthermore, JSON values can be \u201cflattened\u201d to key/value pairs using flatten() where each key is a JSON Pointer. The original value can be restored by \u201cunflattening\u201d the flattened value using unflatten() . \ud83c\udfe5 JSON Patch ( RFC 6902 ) support. A JSON Patch is a JSON value that describes the required edit operations (add, change, remove, \u2026) to transform a JSON value into another one. A JSON Patch can be created with function diff(const basic_json&) and applied with patch(const basic_json&) . Note the created patches use a rather primitive algorithm so far and leave room for improvement. \ud83c\uddea\ud83c\uddfa The code is now locale-independent : Floating-point numbers are always serialized with a period ( . ) as decimal separator and ignores different settings from the locale. \ud83c\udf7a Homebrew support: Install the library with brew tap nlohmann/json && brew install nlohmann_json . Added constructor to create a JSON value by parsing a std::istream (e.g., std::stringstream or std::ifstream ). Added noexcept specifier to basic_json(boolean_t) , basic_json(const number_integer_t) , basic_json(const int) , basic_json(const number_float_t) , iterator functions ( begin() , end() , etc.) When parsing numbers, the sign of 0.0 (vs. -0.0 ) is preserved. Improved MSVC 2015, Android, and MinGW support. See README for more information. Improved test coverage (added 2,225,386 tests). Removed some misuses of std::move . Fixed several compiler warnings. Improved error messages from JSON parser. Updated to re2c to version 0.16 to use a minimal DFAs for the lexer. Updated test suite to use Catch version 1.5.6. Made type getters ( is_number , etc.) and const value access constexpr . Functions push_back and operator+= now work with key/value pairs passed as initializer list, e.g. j_object += {\"key\", 1} . Overworked CMakeLists.txt to make it easier to integrate the library into other projects.","title":"Changes"},{"location":"home/releases/#notes","text":"Parser error messages are still very vague and contain no information on the error location. The implemented diff function is rather primitive and does not create minimal diffs. The name of function iteration_wrapper may change in the future and the function will be deprecated in the next release. Roundtripping (i.e., parsing a JSON value from a string, serializing it, and comparing the strings) of floating-point numbers is not 100% accurate. Note that RFC 8259 defines no format to internally represent numbers and states not requirement for roundtripping. Nevertheless, benchmarks like Native JSON Benchmark treat roundtripping deviations as conformance errors.","title":"Notes"},{"location":"home/releases/#v110","text":"Files json.hpp (257 KB) json.hpp.asc (1 KB) Release date: 2016-01-24 SHA-256: c0cf0e3017798ca6bb18e757ebc570d21a3bdac877845e2b9e9573d183ed2f05","title":"v1.1.0"},{"location":"home/releases/#summary_28","text":"This release fixes several small bugs and adds functionality in a backwards-compatible manner. Compared to the last version (1.0.0) , the following changes have been made:","title":"Summary"},{"location":"home/releases/#changes_14","text":"Fixed : Floating-point numbers are now serialized and deserialized properly such that rountripping works in more cases. [#185, #186, #190, #191, #194] Added : The code now contains assertions to detect undefined behavior during development. As the standard function assert is used, the assertions can be switched off by defining the preprocessor symbol NDEBUG during compilation. [#168] Added : It is now possible to get a reference to the stored values via the newly added function get_ref() . [#128, #184] Fixed : Access to object values via keys ( operator[] ) now works with all kind of string representations. [#171, #189] Fixed : The code now compiles again with Microsoft Visual Studio 2015 . [#144, #167, #188] Fixed : All required headers are now included. Fixed : Typos and other small issues. [#162, #166, #175, #177, #179, #180]","title":"Changes"},{"location":"home/releases/#notes_1","text":"There are still known open issues (#178, #187) which will be fixed in version 2.0.0. However, these fixes will require a small API change and will not be entirely backwards-compatible.","title":"Notes"},{"location":"home/releases/#v100","text":"Files json.hpp (243 KB) json.hpp.asc (1 KB) Release date: 2015-12-28 SHA-256: 767dc2fab1819d7b9e19b6e456d61e38d21ef7182606ecf01516e3f5230446de","title":"v1.0.0"},{"location":"home/releases/#summary_29","text":"This is the first official release. Compared to the prerelease version 1.0.0-rc1 , only a few minor improvements have been made:","title":"Summary"},{"location":"home/releases/#changes_15","text":"Changed : A UTF-8 byte order mark is silently ignored. Changed : sprintf is no longer used. Changed : iterator_wrapper also works for const objects; note: the name may change! Changed : Error messages during deserialization have been improved. Added : The parse function now also works with type std::istream&& . Added : Function value(key, default_value) returns either a copy of an object's element at the specified key or a given default value if no element with the key exists. Added : Public functions are tagged with the version they were introduced. This shall allow for better versioning in the future. Added : All public functions and types are documented (see http://nlohmann.github.io/json/doxygen/ ) including executable examples. Added : Allocation of all types (in particular arrays, strings, and objects) is now exception-safe. Added : They descriptions of thrown exceptions have been overworked and are part of the tests suite and documentation.","title":"Changes"},{"location":"home/sponsors/","text":"Sponsors \u00b6 You can sponsor this library at GitHub Sponsors . Named Sponsors \u00b6 Michael Hartmann Stefan Hagen Steve Sperandeo Robert Jefe Lindst\u00e4dt Steve Wagner Thanks everyone!","title":"Sponsors"},{"location":"home/sponsors/#sponsors","text":"You can sponsor this library at GitHub Sponsors .","title":"Sponsors"},{"location":"home/sponsors/#named-sponsors","text":"Michael Hartmann Stefan Hagen Steve Sperandeo Robert Jefe Lindst\u00e4dt Steve Wagner Thanks everyone!","title":"Named Sponsors"},{"location":"integration/","text":"Header only \u00b6 json.hpp is the single required file in single_include/nlohmann or released here . 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 for forward declarations.","title":"Header only"},{"location":"integration/#header-only","text":"json.hpp is the single required file in single_include/nlohmann or released here . 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 for forward declarations.","title":"Header only"},{"location":"integration/cmake/","text":"CMake \u00b6 Integration \u00b6 You can use the nlohmann_json::nlohmann_json interface target in CMake. This target populates the appropriate usage requirements for INTERFACE_INCLUDE_DIRECTORIES to point to the appropriate include directories and INTERFACE_COMPILE_FEATURES for the necessary C++11 flags. External \u00b6 To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration: Example CMakeLists.txt cmake_minimum_required ( VERSION 3.1 ) project ( ExampleProject LANGUAGES CXX ) find_package ( nlohmann_json 3.11.2 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 \u00b6 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.1 ) 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 \u00b6 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.11.2 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 \u00b6 Since CMake v3.11, FetchContent can be used to automatically download a release as a dependency at configure type. 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.11.2/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.11.2 ) However, the repository https://github.com/nlohmann/json download size is quite large. You might want to depend on a smaller repository. For instance, you might want to replace the URL in the example by https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent . CMake Options \u00b6 JSON_BuildTests \u00b6 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 \u00b6 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 \u00b6 Enable extended diagnostic messages by defining macro JSON_DIAGNOSTICS . This option is OFF by default. JSON_DisableEnumSerialization \u00b6 Disable default enum serialization by defining the macro JSON_DISABLE_ENUM_SERIALIZATION . This option is OFF by default. JSON_FastTests \u00b6 Skip expensive/slow test suites. This option is OFF by default. Depends on JSON_BuildTests . JSON_GlobalUDLs \u00b6 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 \u00b6 Enable implicit conversions by defining macro JSON_USE_IMPLICIT_CONVERSIONS . This option is ON by default. JSON_Install \u00b6 Install CMake targets during install step. This option is ON by default if the library's CMake project is the top project. JSON_MultipleHeaders \u00b6 Use non-amalgamated version of the library. This option is OFF by default. JSON_SystemInclude \u00b6 Treat the library headers like system headers (i.e., adding SYSTEM to the target_include_directories call) to checks for this library by tools like Clang-Tidy. This option is OFF by default. JSON_Valgrind \u00b6 Execute test suite with Valgrind . This option is OFF by default. Depends on JSON_BuildTests .","title":"CMake"},{"location":"integration/cmake/#cmake","text":"","title":"CMake"},{"location":"integration/cmake/#integration","text":"You can use the nlohmann_json::nlohmann_json interface target in CMake. This target populates the appropriate usage requirements for INTERFACE_INCLUDE_DIRECTORIES to point to the appropriate include directories and INTERFACE_COMPILE_FEATURES for the necessary C++11 flags.","title":"Integration"},{"location":"integration/cmake/#external","text":"To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration: Example CMakeLists.txt cmake_minimum_required ( VERSION 3.1 ) project ( ExampleProject LANGUAGES CXX ) find_package ( nlohmann_json 3.11.2 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.","title":"External"},{"location":"integration/cmake/#embedded","text":"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.1 ) 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.","title":"Embedded"},{"location":"integration/cmake/#supporting-both","text":"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.11.2 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.","title":"Supporting Both"},{"location":"integration/cmake/#fetchcontent","text":"Since CMake v3.11, FetchContent can be used to automatically download a release as a dependency at configure type. 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.11.2/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.11.2 ) However, the repository https://github.com/nlohmann/json download size is quite large. You might want to depend on a smaller repository. For instance, you might want to replace the URL in the example by https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent .","title":"FetchContent"},{"location":"integration/cmake/#cmake-options","text":"","title":"CMake Options"},{"location":"integration/cmake/#json_buildtests","text":"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.","title":"JSON_BuildTests"},{"location":"integration/cmake/#json_ci","text":"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.","title":"JSON_CI"},{"location":"integration/cmake/#json_diagnostics","text":"Enable extended diagnostic messages by defining macro JSON_DIAGNOSTICS . This option is OFF by default.","title":"JSON_Diagnostics"},{"location":"integration/cmake/#json_disableenumserialization","text":"Disable default enum serialization by defining the macro JSON_DISABLE_ENUM_SERIALIZATION . This option is OFF by default.","title":"JSON_DisableEnumSerialization"},{"location":"integration/cmake/#json_fasttests","text":"Skip expensive/slow test suites. This option is OFF by default. Depends on JSON_BuildTests .","title":"JSON_FastTests"},{"location":"integration/cmake/#json_globaludls","text":"Place user-defined string literals in the global namespace by defining the macro JSON_USE_GLOBAL_UDLS . This option is OFF by default.","title":"JSON_GlobalUDLs"},{"location":"integration/cmake/#json_implicitconversions","text":"Enable implicit conversions by defining macro JSON_USE_IMPLICIT_CONVERSIONS . This option is ON by default.","title":"JSON_ImplicitConversions"},{"location":"integration/cmake/#json_install","text":"Install CMake targets during install step. This option is ON by default if the library's CMake project is the top project.","title":"JSON_Install"},{"location":"integration/cmake/#json_multipleheaders","text":"Use non-amalgamated version of the library. This option is OFF by default.","title":"JSON_MultipleHeaders"},{"location":"integration/cmake/#json_systeminclude","text":"Treat the library headers like system headers (i.e., adding SYSTEM to the target_include_directories call) to checks for this library by tools like Clang-Tidy. This option is OFF by default.","title":"JSON_SystemInclude"},{"location":"integration/cmake/#json_valgrind","text":"Execute test suite with Valgrind . This option is OFF by default. Depends on JSON_BuildTests .","title":"JSON_Valgrind"},{"location":"integration/migration_guide/","text":"Migration Guide \u00b6 This page collects some guidelines on how to future-proof your code for future versions of this library. Replace deprecated functions \u00b6 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 to report which function to use instead. Parsing \u00b6 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&) instead. Deprecated Future-proof 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 , accept , sax_parse , from_cbor , from_msgpack , from_ubjson , and from_bson 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 Future-proof 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 \u00b6 Comparing JSON Pointers with strings via operator== and operator!= is deprecated since 3.11.2. To compare a json_pointer p with a string s , convert s to a json_pointer first and use json_pointer::operator== or json_pointer::operator!= . Deprecated Future-proof 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 ) is deprecated since 3.11.0. Use json_pointer::to_string instead. Deprecated Future-proof 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 is deprecated since 3.11.0. The string type can now be directly provided. Deprecated Future-proof using my_json = nlohmann :: basic_json < std :: map , std :: vector , my_string_type > ; nlohmann :: json_pointer < my_json > ptr ( \"/foo/bar/1\" ); nlohmann :: json_pointer < my_string_type > 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 \u00b6 The function iterator_wrapper is deprecated since 3.1.0. Please use the member function items instead. Deprecated Future-proof 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&) instead. Deprecated Future-proof 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 to 1 . Deprecated Future-proof #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 #include #include Replace implicit conversions \u00b6 Implicit conversions via operator ValueType 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 , get_to , get_ref , or get_ptr . Deprecated Future-proof Future-proof (alternative) nlohmann :: json j = \"Hello, world!\" ; std :: string s = j ; nlohmann :: json j = \"Hello, world!\" ; auto s = j . get < std :: string > (); nlohmann :: json j = \"Hello, world!\" ; std :: string s ; j . get_to ( s ); You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get . Import namespace literals for UDLs \u00b6 The user-defined string literals operator\"\"_json and operator\"\"_json_pointer will be removed from the global namespace in the next major release of the library. Deprecated Future-proof 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 to 0 and bring the string literals into scope where needed. Do not hard-code the complete library namespace \u00b6 The nlohmann namespace 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 to denote the namespace. Dangerous Future-proof Future-proof (alternative) 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 \u00b6 The details namespace is not part of the public API of the library and can change in any version without announcement. Do not rely on any function or type in the details namespace.","title":"Migration Guide"},{"location":"integration/migration_guide/#migration-guide","text":"This page collects some guidelines on how to future-proof your code for future versions of this library.","title":"Migration Guide"},{"location":"integration/migration_guide/#replace-deprecated-functions","text":"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 to report which function to use instead.","title":"Replace deprecated functions"},{"location":"integration/migration_guide/#parsing","text":"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&) instead. Deprecated Future-proof 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 , accept , sax_parse , from_cbor , from_msgpack , from_ubjson , and from_bson 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 Future-proof 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 ));","title":"Parsing"},{"location":"integration/migration_guide/#json-pointers","text":"Comparing JSON Pointers with strings via operator== and operator!= is deprecated since 3.11.2. To compare a json_pointer p with a string s , convert s to a json_pointer first and use json_pointer::operator== or json_pointer::operator!= . Deprecated Future-proof 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 ) is deprecated since 3.11.0. Use json_pointer::to_string instead. Deprecated Future-proof 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 is deprecated since 3.11.0. The string type can now be directly provided. Deprecated Future-proof using my_json = nlohmann :: basic_json < std :: map , std :: vector , my_string_type > ; nlohmann :: json_pointer < my_json > ptr ( \"/foo/bar/1\" ); nlohmann :: json_pointer < my_string_type > 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 .","title":"JSON Pointers"},{"location":"integration/migration_guide/#miscellaneous-functions","text":"The function iterator_wrapper is deprecated since 3.1.0. Please use the member function items instead. Deprecated Future-proof 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&) instead. Deprecated Future-proof 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 to 1 . Deprecated Future-proof #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 1 #include #include ","title":"Miscellaneous functions"},{"location":"integration/migration_guide/#replace-implicit-conversions","text":"Implicit conversions via operator ValueType 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 , get_to , get_ref , or get_ptr . Deprecated Future-proof Future-proof (alternative) nlohmann :: json j = \"Hello, world!\" ; std :: string s = j ; nlohmann :: json j = \"Hello, world!\" ; auto s = j . get < std :: string > (); nlohmann :: json j = \"Hello, world!\" ; std :: string s ; j . get_to ( s ); You can prepare existing code by already defining JSON_USE_IMPLICIT_CONVERSIONS to 0 and replace any implicit conversions with calls to get .","title":"Replace implicit conversions"},{"location":"integration/migration_guide/#import-namespace-literals-for-udls","text":"The user-defined string literals operator\"\"_json and operator\"\"_json_pointer will be removed from the global namespace in the next major release of the library. Deprecated Future-proof 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 to 0 and bring the string literals into scope where needed.","title":"Import namespace literals for UDLs"},{"location":"integration/migration_guide/#do-not-hard-code-the-complete-library-namespace","text":"The nlohmann namespace 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 to denote the namespace. Dangerous Future-proof Future-proof (alternative) 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 ; }","title":"Do not hard-code the complete library namespace"},{"location":"integration/migration_guide/#do-not-use-the-details-namespace","text":"The details namespace is not part of the public API of the library and can change in any version without announcement. Do not rely on any function or type in the details namespace.","title":"Do not use the details namespace"},{"location":"integration/package_managers/","text":"Package Managers \u00b6 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.1.0\" }, \"copyright\" : \"(C) 2013-2022 Niels Lohmann\" , \"name\" : \"JSON for Modern C++\" , \"platform\" : \"apple\" , \"url\" : \"https://github.com/nlohmann/json\" , \"version\" : { \"major\" : 3 , \"minor\" : 11 , \"patch\" : 2 , \"string\" : \"3.11.2\" } } Homebrew \u00b6 If you are using OS X and Homebrew , just type brew install nlohmann-json and you're set. If you want the bleeding edge rather than the latest release, use brew install nlohmann-json --HEAD instead. See nlohmann-json for more information. Example Create the following file: example.cpp #include #include #include using json = nlohmann :: json ; int main () { std :: cout << std :: setw ( 4 ) << json :: meta () << std :: endl ; } Install the package brew install nlohmann-json Determine the include path, which defaults to /usr/local/Cellar/nlohmann-json/$version/include , where $version is the version of the library, e.g. 3.7.3 . The path of the library can be determined with brew list nlohmann-json Compile the code. For instance, the code can be compiled using Clang with clang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std = c++11 -o example The formula is updated automatically. Meson \u00b6 If you are using the Meson Build System , add this source tree as a meson subproject . You may also use the include.zip published in this project's Releases to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from Meson WrapDB , or simply 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, simply have your build system require the nlohmann_json pkg-config dependency. In Meson, it is preferred to use the dependency() object with a subproject fallback, rather than using the subproject directly. Bazel \u00b6 This repository provides a Bazel WORKSPACE.bazel and a corresponding BUILD.bazel file. Therefore, this repository can be referenced by workspace rules such as http_archive , git_repository , or local_repository from other Bazel workspaces. To use the library you only need to depend on the target @nlohmann_json//:json (e.g. via deps attribute). Conan \u00b6 If you are using Conan 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. Please file issues here if you experience problems with the packages. Example Create the following files: Conanfile.txt [requires] nlohmann_json/3.7.3 [generators] cmake CMakeLists.txt project ( json_example ) cmake_minimum_required ( VERSION 2.8.12 ) add_definitions ( \"-std=c++11\" ) include ( ${ CMAKE_BINARY_DIR } /conanbuildinfo.cmake ) conan_basic_setup () add_executable ( json_example example.cpp ) target_link_libraries ( json_example ${ CONAN_LIBS } ) example.cpp #include #include using json = nlohmann :: json ; int main () { std :: cout << json :: meta () << std :: endl ; } Build: mkdir build cd build conan install .. cmake .. cmake --build . The package is updated automatically. Spack \u00b6 If you are using Spack to manage your dependencies, you can use the nlohmann-json package . Please see the spack project for any issues regarding the packaging. Hunter \u00b6 If you are using hunter on your project for external dependencies, then you can use the nlohmann_json package . Please see the hunter project for any issues regarding the packaging. Buckaroo \u00b6 If you are using Buckaroo , you can install this library's module with buckaroo add github.com/buckaroo-pm/nlohmann-json . Please file issues here . There is a demo repo here . vcpkg \u00b6 If you are using vcpkg on your project for external dependencies, then you can install the nlohmann-json package with vcpkg install nlohmann-json and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging. Example Create the following files: CMakeLists.txt project ( json_example ) cmake_minimum_required ( VERSION 2.8.12 ) 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 using json = nlohmann :: json ; int main () { std :: cout << json :: meta () << std :: endl ; } Install package: vcpkg install nlohmann-json Build: mkdir build cd build cmake .. -DCMAKE_TOOLCHAIN_FILE = /path/to/vcpkg/scripts/buildsystems/vcpkg.cmake cmake --build . Note you need to adjust /path/to/vcpkg/scripts/buildsystems/vcpkg.cmake to your system. cget \u00b6 If you are using cget , you can install the latest development version with cget install nlohmann/json . A specific version can be installed with cget install nlohmann/json@v3.1.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 ). cget reads directly from the GitHub repository and is always up-to-date. CocoaPods \u00b6 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 . NuGet \u00b6 If you are using NuGet , you can use the package nlohmann.json . Please check this extensive description on how to use the package. Please file issues here . Conda \u00b6 If you are using conda , you can use the package nlohmann_json from conda-forge executing conda install -c conda-forge nlohmann_json . Please file issues here . MSYS2 \u00b6 If you are using MSYS2 , you can use the mingw-w64-nlohmann-json package, just type pacman -S mingw-w64-i686-nlohmann-json or pacman -S mingw-w64-x86_64-nlohmann-json for installation. Please file issues here if you experience problems with the packages. The package is updated automatically. MacPorts \u00b6 If you are using MacPorts , execute sudo port install nlohmann-json to install the nlohmann-json package. The package is updated automatically. build2 \u00b6 If you are using build2 , you can use the nlohmann-json package from the public repository http://cppget.org or directly from the package's sources repository . In your project's manifest file, just add depends: nlohmann-json (probably with some version constraints ). If you are not familiar with using dependencies in build2 , please read this introduction . Please file issues here if you experience problems with the packages. The package is updated automatically. wsjcpp \u00b6 If you are using wsjcpp , you can use the command wsjcpp install \"https://github.com/nlohmann/json:develop\" to get the latest version. Note you can change the branch \":develop\" to an existing tag or another branch. wsjcpp reads directly from the GitHub repository and is always up-to-date. CPM.cmake \u00b6 If you are using CPM.cmake , you can check this example . After adding CPM script to your project, implement the following snippet to your CMake: CPMAddPackage ( NAME nlohmann_json GITHUB_REPOSITORY nlohmann/json VERSION 3.9.1 )","title":"Package Managers"},{"location":"integration/package_managers/#package-managers","text":"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.1.0\" }, \"copyright\" : \"(C) 2013-2022 Niels Lohmann\" , \"name\" : \"JSON for Modern C++\" , \"platform\" : \"apple\" , \"url\" : \"https://github.com/nlohmann/json\" , \"version\" : { \"major\" : 3 , \"minor\" : 11 , \"patch\" : 2 , \"string\" : \"3.11.2\" } }","title":"Package Managers"},{"location":"integration/package_managers/#homebrew","text":"If you are using OS X and Homebrew , just type brew install nlohmann-json and you're set. If you want the bleeding edge rather than the latest release, use brew install nlohmann-json --HEAD instead. See nlohmann-json for more information. Example Create the following file: example.cpp #include #include #include using json = nlohmann :: json ; int main () { std :: cout << std :: setw ( 4 ) << json :: meta () << std :: endl ; } Install the package brew install nlohmann-json Determine the include path, which defaults to /usr/local/Cellar/nlohmann-json/$version/include , where $version is the version of the library, e.g. 3.7.3 . The path of the library can be determined with brew list nlohmann-json Compile the code. For instance, the code can be compiled using Clang with clang++ example.cpp -I/usr/local/Cellar/nlohmann-json/3.7.3/include -std = c++11 -o example The formula is updated automatically.","title":"Homebrew"},{"location":"integration/package_managers/#meson","text":"If you are using the Meson Build System , add this source tree as a meson subproject . You may also use the include.zip published in this project's Releases to reduce the size of the vendored source tree. Alternatively, you can get a wrap file by downloading it from Meson WrapDB , or simply 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, simply have your build system require the nlohmann_json pkg-config dependency. In Meson, it is preferred to use the dependency() object with a subproject fallback, rather than using the subproject directly.","title":"Meson"},{"location":"integration/package_managers/#bazel","text":"This repository provides a Bazel WORKSPACE.bazel and a corresponding BUILD.bazel file. Therefore, this repository can be referenced by workspace rules such as http_archive , git_repository , or local_repository from other Bazel workspaces. To use the library you only need to depend on the target @nlohmann_json//:json (e.g. via deps attribute).","title":"Bazel"},{"location":"integration/package_managers/#conan","text":"If you are using Conan 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. Please file issues here if you experience problems with the packages. Example Create the following files: Conanfile.txt [requires] nlohmann_json/3.7.3 [generators] cmake CMakeLists.txt project ( json_example ) cmake_minimum_required ( VERSION 2.8.12 ) add_definitions ( \"-std=c++11\" ) include ( ${ CMAKE_BINARY_DIR } /conanbuildinfo.cmake ) conan_basic_setup () add_executable ( json_example example.cpp ) target_link_libraries ( json_example ${ CONAN_LIBS } ) example.cpp #include #include using json = nlohmann :: json ; int main () { std :: cout << json :: meta () << std :: endl ; } Build: mkdir build cd build conan install .. cmake .. cmake --build . The package is updated automatically.","title":"Conan"},{"location":"integration/package_managers/#spack","text":"If you are using Spack to manage your dependencies, you can use the nlohmann-json package . Please see the spack project for any issues regarding the packaging.","title":"Spack"},{"location":"integration/package_managers/#hunter","text":"If you are using hunter on your project for external dependencies, then you can use the nlohmann_json package . Please see the hunter project for any issues regarding the packaging.","title":"Hunter"},{"location":"integration/package_managers/#buckaroo","text":"If you are using Buckaroo , you can install this library's module with buckaroo add github.com/buckaroo-pm/nlohmann-json . Please file issues here . There is a demo repo here .","title":"Buckaroo"},{"location":"integration/package_managers/#vcpkg","text":"If you are using vcpkg on your project for external dependencies, then you can install the nlohmann-json package with vcpkg install nlohmann-json and follow the then displayed descriptions. Please see the vcpkg project for any issues regarding the packaging. Example Create the following files: CMakeLists.txt project ( json_example ) cmake_minimum_required ( VERSION 2.8.12 ) 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 using json = nlohmann :: json ; int main () { std :: cout << json :: meta () << std :: endl ; } Install package: vcpkg install nlohmann-json Build: mkdir build cd build cmake .. -DCMAKE_TOOLCHAIN_FILE = /path/to/vcpkg/scripts/buildsystems/vcpkg.cmake cmake --build . Note you need to adjust /path/to/vcpkg/scripts/buildsystems/vcpkg.cmake to your system.","title":"vcpkg"},{"location":"integration/package_managers/#cget","text":"If you are using cget , you can install the latest development version with cget install nlohmann/json . A specific version can be installed with cget install nlohmann/json@v3.1.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 ). cget reads directly from the GitHub repository and is always up-to-date.","title":"cget"},{"location":"integration/package_managers/#cocoapods","text":"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 .","title":"CocoaPods"},{"location":"integration/package_managers/#nuget","text":"If you are using NuGet , you can use the package nlohmann.json . Please check this extensive description on how to use the package. Please file issues here .","title":"NuGet"},{"location":"integration/package_managers/#conda","text":"If you are using conda , you can use the package nlohmann_json from conda-forge executing conda install -c conda-forge nlohmann_json . Please file issues here .","title":"Conda"},{"location":"integration/package_managers/#msys2","text":"If you are using MSYS2 , you can use the mingw-w64-nlohmann-json package, just type pacman -S mingw-w64-i686-nlohmann-json or pacman -S mingw-w64-x86_64-nlohmann-json for installation. Please file issues here if you experience problems with the packages. The package is updated automatically.","title":"MSYS2"},{"location":"integration/package_managers/#macports","text":"If you are using MacPorts , execute sudo port install nlohmann-json to install the nlohmann-json package. The package is updated automatically.","title":"MacPorts"},{"location":"integration/package_managers/#build2","text":"If you are using build2 , you can use the nlohmann-json package from the public repository http://cppget.org or directly from the package's sources repository . In your project's manifest file, just add depends: nlohmann-json (probably with some version constraints ). If you are not familiar with using dependencies in build2 , please read this introduction . Please file issues here if you experience problems with the packages. The package is updated automatically.","title":"build2"},{"location":"integration/package_managers/#wsjcpp","text":"If you are using wsjcpp , you can use the command wsjcpp install \"https://github.com/nlohmann/json:develop\" to get the latest version. Note you can change the branch \":develop\" to an existing tag or another branch. wsjcpp reads directly from the GitHub repository and is always up-to-date.","title":"wsjcpp"},{"location":"integration/package_managers/#cpmcmake","text":"If you are using CPM.cmake , you can check this example . After adding CPM script to your project, implement the following snippet to your CMake: CPMAddPackage ( NAME nlohmann_json GITHUB_REPOSITORY nlohmann/json VERSION 3.9.1 )","title":"CPM.cmake"},{"location":"integration/pkg-config/","text":"Pkg-config \u00b6 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 )","title":"Pkg-config"},{"location":"integration/pkg-config/#pkg-config","text":"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 )","title":"Pkg-config"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..21a2a4d1f --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,1118 @@ + + + + https://json.nlohmann.me/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/operator_gtgt/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/operator_literal_json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/operator_literal_json_pointer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/operator_ltlt/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/ordered_json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/ordered_map/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/adl_serializer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/adl_serializer/from_json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/adl_serializer/to_json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/accept/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/array/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/array_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/at/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/back/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/basic_json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/begin/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/binary/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/binary_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/boolean_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/cbegin/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/cbor_tag_handler_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/cend/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/clear/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/contains/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/count/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/crbegin/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/crend/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/default_object_comparator_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/diff/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/dump/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/emplace/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/emplace_back/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/empty/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/end/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/erase/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/error_handler_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/exception/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/find/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/flatten/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/from_bjdata/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/from_bson/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/from_cbor/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/from_msgpack/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/from_ubjson/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/front/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/get/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/get_allocator/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/get_binary/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/get_ptr/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/get_ref/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/get_to/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/input_format_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/insert/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/invalid_iterator/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_array/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_binary/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_boolean/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_discarded/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_null/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_number/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_number_float/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_number_integer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_number_unsigned/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_object/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_primitive/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_string/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/is_structured/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/items/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/json_base_class_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/json_serializer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/max_size/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/merge_patch/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/meta/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/number_float_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/number_integer_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/number_unsigned_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/object/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/object_comparator_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/object_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator%2B%3D/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator%3D/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator%5B%5D/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_ValueType/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_eq/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_ge/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_gt/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_le/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_lt/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_ne/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_spaceship/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/operator_value_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/other_error/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/out_of_range/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/parse/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/parse_error/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/parse_event_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/parser_callback_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/patch/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/patch_inplace/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/push_back/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/rbegin/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/rend/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/sax_parse/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/size/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/std_hash/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/std_swap/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/string_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/swap/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/to_bjdata/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/to_bson/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/to_cbor/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/to_msgpack/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/to_string/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/to_ubjson/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/type/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/type_error/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/type_name/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/unflatten/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/update/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/value/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/value_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/basic_json/~basic_json/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/byte_container_with_subtype/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/back/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/empty/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/json_pointer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/operator_eq/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/operator_ne/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/operator_slash/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/operator_slasheq/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/operator_string_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/parent_pointer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/pop_back/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/push_back/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/string_t/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_pointer/to_string/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/binary/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/boolean/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/end_array/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/end_object/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/key/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/null/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/number_float/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/number_integer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/number_unsigned/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/parse_error/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/start_array/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/start_object/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/json_sax/string/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_assert/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_diagnostics/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_disable_enum_serialization/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_has_cpp_11/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_has_filesystem/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_has_ranges/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_has_three_way_comparison/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_no_io/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_noexception/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_skip_library_version_check/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_skip_unsupported_compiler_check/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_throw_user/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_use_global_udls/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_use_implicit_conversions/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/json_use_legacy_discarded_value_comparison/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/nlohmann_json_namespace/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/nlohmann_json_namespace_begin/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/nlohmann_json_namespace_no_version/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/nlohmann_json_serialize_enum/ + 2023-03-08 + daily + + + https://json.nlohmann.me/api/macros/nlohmann_json_version_major/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/arbitrary_types/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/assertions/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/binary_values/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/comments/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/enum_conversion/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/iterators/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/json_patch/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/json_pointer/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/macros/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/merge_patch/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/namespace/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/object_order/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/binary_formats/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/binary_formats/bjdata/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/binary_formats/bson/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/binary_formats/cbor/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/binary_formats/messagepack/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/binary_formats/ubjson/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/element_access/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/element_access/checked_access/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/element_access/default_value/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/element_access/unchecked_access/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/parsing/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/parsing/json_lines/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/parsing/parse_exceptions/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/parsing/parser_callbacks/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/parsing/sax_interface/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/types/ + 2023-03-08 + daily + + + https://json.nlohmann.me/features/types/number_handling/ + 2023-03-08 + daily + + + https://json.nlohmann.me/home/code_of_conduct/ + 2023-03-08 + daily + + + https://json.nlohmann.me/home/design_goals/ + 2023-03-08 + daily + + + https://json.nlohmann.me/home/exceptions/ + 2023-03-08 + daily + + + https://json.nlohmann.me/home/faq/ + 2023-03-08 + daily + + + https://json.nlohmann.me/home/license/ + 2023-03-08 + daily + + + https://json.nlohmann.me/home/releases/ + 2023-03-08 + daily + + + https://json.nlohmann.me/home/sponsors/ + 2023-03-08 + daily + + + https://json.nlohmann.me/integration/ + 2023-03-08 + daily + + + https://json.nlohmann.me/integration/cmake/ + 2023-03-08 + daily + + + https://json.nlohmann.me/integration/migration_guide/ + 2023-03-08 + daily + + + https://json.nlohmann.me/integration/package_managers/ + 2023-03-08 + daily + + + https://json.nlohmann.me/integration/pkg-config/ + 2023-03-08 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..8f62c682523841c0fba5976ddefe0c46a2713125 GIT binary patch literal 1642 zcmV-w29^0AiwFqif(T>+|8r?{Wo=<_E_iKh0NtJ6Z`(Ey$KU%`1OfWkIBij&8`2ag zhW!QIUWpTRl9*5=OHy&XhyCp%X~jR%rNdr^`_2erTb6~7Pp9MYcz3$_{5ac-2ad^j z_v!NO)%E2CJMDYp#!r{Oef{;#$IH*RuWpuT6X%PvvrC^Yr<}vjo6UB+y-FtYOd(zQ zIBt@j%A2%VH*T)4e!9GUbx|Jm0Q*<%abvx{tw%}aFn7tjD`)*QlXF)yZ*DgA%_# zYRqGn&S;BrM6wD&o~NuTc;m`j@yywZ)q&V^oG?^7#0% z#&-?rUJp*o1`iB+(Xd1#aa;1x#I|gss`&3mi~{xHKlLFlJVk_86C*AwqG28 zKn>B%CYuL_piMa%H=>{}Ixi7IWi!tJORg;;xx8nk3r0flz#Fpo#MKkvnI2Utr~srK zM^=Hdo)BOWBF3lw48qlQ?#=)aKY23<$SBSXWJbmcjX=7V+Pr@E<@NhtfOw%`KYV%p z0f<-qPIlq1yTCxq{0#_pM3U?XWXF_6lB`9NtV5D)3ZywrCIB%%RI3Z&G~}sxyDh;B z0CvgB4=UD!%cm_)ZbHFC(SQ~9fgOZP-f*MRWNl6E#XyD#*ECFJ97u|HSkeTN-;Gj^ zf>Di<=uv?T1Q|OoiOB?JxmIEMTJN`E}$6c=LHld`Mj{A zEZ7%Rlq~rS5pAuMDAT^i>SzWK>*8Q)rIt{}C;*YRU>XP}f)n+p{N_Eo%xdj4!BK5Z zo>W>o$%gd@#Q(2f)B2PE^OwmZFn!{TOfQ-opq=U&qTqPq8K>lq5oe%i3LrmW;_q=C zL*XVXH{SRIVlbr;9)vuD4ixJOB#@~HJ}8v&Li%Fa87z|8N)Pw#Ycc3iI-clq-6N&w zO5Fn{yIypq_8F+?RQm(zJ&PBn;9}~J(+SCThD8Hawi+-z?Bz8V=3R^JMXnjXkExk=3#AXiGXj6;g z-KyXy=$1#)yJL^FwdM`QY(H&QJrBmQYAI%A`W%-ex7X5-*j+gi?=woV85ajmvC-Hgq3FJR2TaL+ z;Q?}O57zF_4ln@iJL4xHQn7`UF9IjoL((%`p+%K1;TDsSXk?+~l`m0?tz10%RF*Tr2p;h^;Jc(D&a6i5&1L0u)gWgih`B^00wd`xBvhE literal 0 HcmV?d00001