From 724b06ccb8c2eb587397b58ea3755913521c4e44 Mon Sep 17 00:00:00 2001 From: "pangpang@hi-nginx.com" Date: Tue, 28 Jun 2022 14:51:13 +0800 Subject: [PATCH] update nginx to v1.23.0 update json.hpp update jsoncons update pybind11 --- CHANGES | 31 +- CHANGES.ru | 32 +- auto/options | 3 + auto/os/conf | 2 +- auto/os/linux | 16 + auto/sources | 3 +- contrib/vim/syntax/nginx.vim | 1012 +-- module/lib/json.hpp | 6338 +++-------------- module/lib/jsoncons/basic_json.hpp | 1197 ++-- .../lib/jsoncons/config/compiler_support.hpp | 4 +- .../lib/jsoncons/config/jsoncons_config.hpp | 58 +- module/lib/jsoncons/config/version.hpp | 2 +- module/lib/jsoncons/converter.hpp | 20 +- module/lib/jsoncons/decode_traits.hpp | 15 +- module/lib/jsoncons/detail/parse_number.hpp | 8 +- module/lib/jsoncons/detail/string_view.hpp | 13 +- module/lib/jsoncons/detail/string_wrapper.hpp | 8 +- module/lib/jsoncons/json_array.hpp | 324 + module/lib/jsoncons/json_encoder.hpp | 54 +- ...on_container_types.hpp => json_object.hpp} | 584 +- module/lib/jsoncons/json_traits_macros.hpp | 46 +- module/lib/jsoncons/json_type.hpp | 76 +- module/lib/jsoncons/json_visitor2.hpp | 10 +- module/lib/jsoncons/staj_cursor.hpp | 26 +- module/lib/jsoncons/tag_type.hpp | 42 +- module/lib/pybind11/attr.h | 250 +- module/lib/pybind11/buffer_info.h | 123 +- module/lib/pybind11/cast.h | 901 ++- module/lib/pybind11/chrono.h | 139 +- module/lib/pybind11/complex.h | 29 +- module/lib/pybind11/detail/class.h | 241 +- module/lib/pybind11/detail/common.h | 919 ++- module/lib/pybind11/detail/descr.h | 87 +- module/lib/pybind11/detail/init.h | 268 +- module/lib/pybind11/detail/internals.h | 253 +- module/lib/pybind11/detail/type_caster_base.h | 518 +- module/lib/pybind11/detail/typeid.h | 16 +- module/lib/pybind11/eigen.h | 481 +- module/lib/pybind11/embed.h | 64 +- module/lib/pybind11/eval.h | 103 +- module/lib/pybind11/functional.h | 30 +- module/lib/pybind11/gil.h | 69 +- module/lib/pybind11/iostream.h | 66 +- module/lib/pybind11/numpy.h | 1207 ++-- module/lib/pybind11/operators.h | 253 +- module/lib/pybind11/options.h | 41 +- module/lib/pybind11/pybind11.h | 1697 +++-- module/lib/pybind11/pytypes.h | 1007 ++- module/lib/pybind11/stl.h | 197 +- module/lib/pybind11/stl/filesystem.h | 50 +- module/lib/pybind11/stl_bind.h | 562 +- module/lib/utils.cpp | 14 +- src/core/nginx.h | 4 +- src/core/ngx_connection.h | 1 + src/core/ngx_hash.h | 7 +- src/core/ngx_resolver.c | 1 + src/event/modules/ngx_iocp_module.c | 380 + src/event/modules/ngx_iocp_module.h | 22 + src/event/ngx_event.h | 7 +- src/event/ngx_event_acceptex.c | 229 + src/event/ngx_event_connect.c | 2 + src/event/ngx_event_connectex.c | 206 + src/event/ngx_event_openssl.c | 6 + src/event/ngx_event_udp.c | 94 +- src/event/ngx_event_udp.h | 58 + src/http/modules/ngx_http_auth_basic_module.c | 1 + .../modules/ngx_http_auth_request_module.c | 12 +- src/http/modules/ngx_http_dav_module.c | 1 + src/http/modules/ngx_http_fastcgi_module.c | 74 +- src/http/modules/ngx_http_geo_module.c | 6 +- src/http/modules/ngx_http_geoip_module.c | 12 +- src/http/modules/ngx_http_grpc_module.c | 13 +- .../modules/ngx_http_gzip_filter_module.c | 1 + .../modules/ngx_http_gzip_static_module.c | 1 + .../modules/ngx_http_headers_filter_module.c | 55 +- src/http/modules/ngx_http_memcached_module.c | 1 + src/http/modules/ngx_http_mp4_module.c | 2 +- src/http/modules/ngx_http_proxy_module.c | 33 +- .../modules/ngx_http_range_filter_module.c | 3 + src/http/modules/ngx_http_realip_module.c | 7 +- src/http/modules/ngx_http_scgi_module.c | 58 +- src/http/modules/ngx_http_static_module.c | 1 + .../modules/ngx_http_userid_filter_module.c | 19 +- src/http/modules/ngx_http_uwsgi_module.c | 70 +- src/http/modules/perl/nginx.xs | 116 +- src/http/ngx_http.h | 8 +- src/http/ngx_http_core_module.c | 134 +- src/http/ngx_http_core_module.h | 4 +- src/http/ngx_http_file_cache.c | 5 + src/http/ngx_http_parse.c | 60 +- src/http/ngx_http_request.c | 56 +- src/http/ngx_http_request.h | 14 +- src/http/ngx_http_script.c | 1 + src/http/ngx_http_special_response.c | 1 + src/http/ngx_http_upstream.c | 406 +- src/http/ngx_http_upstream.h | 12 +- src/http/ngx_http_variables.c | 160 +- src/http/ngx_http_variables.h | 5 +- src/http/ngx_http_write_filter_module.c | 3 +- src/http/v2/ngx_http_v2.h | 2 +- src/http/v2/ngx_http_v2_filter_module.c | 33 +- src/os/unix/ngx_linux_config.h | 4 + src/os/unix/ngx_readv_chain.c | 4 +- src/os/unix/ngx_recv.c | 4 +- src/os/unix/ngx_udp_sendmsg_chain.c | 226 +- src/os/win32/nginx.ico | Bin 0 -> 1350 bytes src/os/win32/nginx.rc | 6 + src/os/win32/nginx_icon16.xpm | 24 + src/os/win32/nginx_icon32.xpm | 39 + src/os/win32/nginx_icon48.xpm | 55 + src/os/win32/ngx_alloc.c | 44 + src/os/win32/ngx_alloc.h | 27 + src/os/win32/ngx_atomic.h | 69 + src/os/win32/ngx_dlopen.c | 22 + src/os/win32/ngx_dlopen.h | 32 + src/os/win32/ngx_errno.c | 60 + src/os/win32/ngx_errno.h | 71 + src/os/win32/ngx_event_log.c | 99 + src/os/win32/ngx_files.c | 912 +++ src/os/win32/ngx_files.h | 271 + src/os/win32/ngx_os.h | 68 + src/os/win32/ngx_process.c | 238 + src/os/win32/ngx_process.h | 80 + src/os/win32/ngx_process_cycle.c | 1043 +++ src/os/win32/ngx_process_cycle.h | 44 + src/os/win32/ngx_service.c | 134 + src/os/win32/ngx_shmem.c | 161 + src/os/win32/ngx_shmem.h | 33 + src/os/win32/ngx_socket.c | 49 + src/os/win32/ngx_socket.h | 253 + src/os/win32/ngx_stat.c | 34 + src/os/win32/ngx_thread.c | 30 + src/os/win32/ngx_thread.h | 27 + src/os/win32/ngx_time.c | 83 + src/os/win32/ngx_time.h | 51 + src/os/win32/ngx_udp_wsarecv.c | 149 + src/os/win32/ngx_user.c | 23 + src/os/win32/ngx_user.h | 25 + src/os/win32/ngx_win32_config.h | 286 + src/os/win32/ngx_win32_init.c | 329 + src/os/win32/ngx_wsarecv.c | 213 + src/os/win32/ngx_wsarecv_chain.c | 145 + src/os/win32/ngx_wsasend.c | 185 + src/os/win32/ngx_wsasend_chain.c | 296 + src/stream/ngx_stream_proxy_module.c | 13 +- src/stream/ngx_stream_write_filter_module.c | 2 +- 146 files changed, 15970 insertions(+), 11909 deletions(-) create mode 100644 module/lib/jsoncons/json_array.hpp rename module/lib/jsoncons/{json_container_types.hpp => json_object.hpp} (72%) create mode 100644 src/event/modules/ngx_iocp_module.c create mode 100644 src/event/modules/ngx_iocp_module.h create mode 100644 src/event/ngx_event_acceptex.c create mode 100644 src/event/ngx_event_connectex.c create mode 100644 src/event/ngx_event_udp.h create mode 100644 src/os/win32/nginx.ico create mode 100644 src/os/win32/nginx.rc create mode 100644 src/os/win32/nginx_icon16.xpm create mode 100644 src/os/win32/nginx_icon32.xpm create mode 100644 src/os/win32/nginx_icon48.xpm create mode 100644 src/os/win32/ngx_alloc.c create mode 100644 src/os/win32/ngx_alloc.h create mode 100644 src/os/win32/ngx_atomic.h create mode 100644 src/os/win32/ngx_dlopen.c create mode 100644 src/os/win32/ngx_dlopen.h create mode 100644 src/os/win32/ngx_errno.c create mode 100644 src/os/win32/ngx_errno.h create mode 100644 src/os/win32/ngx_event_log.c create mode 100644 src/os/win32/ngx_files.c create mode 100644 src/os/win32/ngx_files.h create mode 100644 src/os/win32/ngx_os.h create mode 100644 src/os/win32/ngx_process.c create mode 100644 src/os/win32/ngx_process.h create mode 100644 src/os/win32/ngx_process_cycle.c create mode 100644 src/os/win32/ngx_process_cycle.h create mode 100644 src/os/win32/ngx_service.c create mode 100644 src/os/win32/ngx_shmem.c create mode 100644 src/os/win32/ngx_shmem.h create mode 100644 src/os/win32/ngx_socket.c create mode 100644 src/os/win32/ngx_socket.h create mode 100644 src/os/win32/ngx_stat.c create mode 100644 src/os/win32/ngx_thread.c create mode 100644 src/os/win32/ngx_thread.h create mode 100644 src/os/win32/ngx_time.c create mode 100644 src/os/win32/ngx_time.h create mode 100644 src/os/win32/ngx_udp_wsarecv.c create mode 100644 src/os/win32/ngx_user.c create mode 100644 src/os/win32/ngx_user.h create mode 100644 src/os/win32/ngx_win32_config.h create mode 100644 src/os/win32/ngx_win32_init.c create mode 100644 src/os/win32/ngx_wsarecv.c create mode 100644 src/os/win32/ngx_wsarecv_chain.c create mode 100644 src/os/win32/ngx_wsasend.c create mode 100644 src/os/win32/ngx_wsasend_chain.c diff --git a/CHANGES b/CHANGES index 6b232cf9..49465bc2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,34 @@ -Changes with nginx 1.22.0 24 May 2022 +Changes with nginx 1.23.0 21 Jun 2022 - *) 1.22.x stable branch. + *) Change in internal API: now header lines are represented as linked + lists. + + *) Change: now nginx combines arbitrary header lines with identical + names when sending to FastCGI, SCGI, and uwsgi backends, in the + $r->header_in() method of the ngx_http_perl_module, and during lookup + of the "$http_...", "$sent_http_...", "$sent_trailer_...", + "$upstream_http_...", and "$upstream_trailer_..." variables. + + *) Bugfix: if there were multiple "Vary" header lines in the backend + response, nginx only used the last of them when caching. + + *) Bugfix: if there were multiple "WWW-Authenticate" header lines in the + backend response and errors with code 401 were intercepted or the + "auth_request" directive was used, nginx only sent the first of the + header lines to the client. + + *) Change: the logging level of the "application data after close + notify" SSL errors has been lowered from "crit" to "info". + + *) Bugfix: connections might hang if nginx was built on Linux 2.6.17 or + newer, but was used on systems without EPOLLRDHUP support, notably + with epoll emulation layers; the bug had appeared in 1.17.5. + Thanks to Marcus Ball. + + *) Bugfix: nginx did not cache the response if the "Expires" response + header line disabled caching, but following "Cache-Control" header + line enabled caching. Changes with nginx 1.21.6 25 Jan 2022 diff --git a/CHANGES.ru b/CHANGES.ru index bd49853b..1339e8df 100644 --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,7 +1,35 @@ -Изменения в nginx 1.22.0 24.05.2022 +Изменения в nginx 1.23.0 21.06.2022 - *) Стабильная ветка 1.22.x. + *) Изменение во внутреннем API: теперь строки заголовков представлены + связными списками. + + *) Изменение: теперь nginx объединяет произвольные строки заголовков с + одинаковыми именами при отправке на FastCGI-, SCGI- и uwsgi-бэкенды, + в методе $r->header_in() модуля ngx_http_perl_module, и при доступе + через переменные "$http_...", "$sent_http_...", "$sent_trailer_...", + "$upstream_http_..." и "$upstream_trailer_...". + + *) Исправление: если в заголовке ответа бэкенда было несколько строк + "Vary", при кэшировании nginx учитывал только последнюю из них. + + *) Исправление: если в заголовке ответа бэкенда было несколько строк + "WWW-Authenticate" и использовался перехват ошибок с кодом 401 от + бэкенда или директива auth_request, nginx пересылал клиенту только + первую из этих строк. + + *) Изменение: уровень логгирования ошибок SSL "application data after + close notify" понижен с уровня crit до info. + + *) Исправление: соединения могли зависать, если nginx был собран на + Linux 2.6.17 и новее, а использовался на системах без поддержки + EPOLLRDHUP, в частности, на системах с эмуляцией epoll; ошибка + появилась в 1.17.5. + Спасибо Marcus Ball. + + *) Исправление: nginx не кэшировал ответ, если строка заголовка ответа + "Expires" запрещала кэширование, а последующая строка заголовка + "Cache-Control" разрешала кэширование. Изменения в nginx 1.21.6 25.01.2022 diff --git a/auto/options b/auto/options index 9236a7f7..76caaf3b 100644 --- a/auto/options +++ b/auto/options @@ -369,6 +369,9 @@ use the \"--with-mail_ssl_module\" option instead" --with-openssl=*) OPENSSL="$value" ;; --with-openssl-opt=*) OPENSSL_OPT="$value" ;; + --with-http-hi-python-version=*) HTTP_HI_PYTHON_VERSION="$value" ;; + --with-http-hi-lua-version=*) HTTP_HI_LUA_VERSION="$value" ;; + --with-md5=*) NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG $0: warning: the \"--with-md5\" option is deprecated" diff --git a/auto/os/conf b/auto/os/conf index 7c6cb691..d7f6e038 100644 --- a/auto/os/conf +++ b/auto/os/conf @@ -110,7 +110,7 @@ case "$NGX_MACHINE" in NGX_MACH_CACHE_LINE=64 ;; - aarch64 ) + aarch64 | arm64) have=NGX_ALIGNMENT value=16 . auto/define NGX_MACH_CACHE_LINE=64 ;; diff --git a/auto/os/linux b/auto/os/linux index 74b58702..0ae701fa 100644 --- a/auto/os/linux +++ b/auto/os/linux @@ -232,4 +232,20 @@ ngx_feature_test="struct crypt_data cd; ngx_include="sys/vfs.h"; . auto/include +# UDP segmentation offloading + +ngx_feature="UDP_SEGMENT" +ngx_feature_name="NGX_HAVE_UDP_SEGMENT" +ngx_feature_run=no +ngx_feature_incs="#include + #include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="socklen_t optlen = sizeof(int); + int val; + getsockopt(0, SOL_UDP, UDP_SEGMENT, &val, &optlen)" +. auto/feature + + CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64" diff --git a/auto/sources b/auto/sources index 156f7979..a539093c 100644 --- a/auto/sources +++ b/auto/sources @@ -89,7 +89,8 @@ EVENT_DEPS="src/event/ngx_event.h \ src/event/ngx_event_timer.h \ src/event/ngx_event_posted.h \ src/event/ngx_event_connect.h \ - src/event/ngx_event_pipe.h" + src/event/ngx_event_pipe.h \ + src/event/ngx_event_udp.h" EVENT_SRCS="src/event/ngx_event.c \ src/event/ngx_event_timer.c \ diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim index 6828cd3e..7d587fc4 100644 --- a/contrib/vim/syntax/nginx.vim +++ b/contrib/vim/syntax/nginx.vim @@ -111,19 +111,14 @@ syn keyword ngxDirectiveControl contained set syn keyword ngxDirectiveError contained error_page syn keyword ngxDirectiveError contained post_action -syn keyword ngxDirectiveDeprecated contained limit_zone syn keyword ngxDirectiveDeprecated contained proxy_downstream_buffer syn keyword ngxDirectiveDeprecated contained proxy_upstream_buffer -syn keyword ngxDirectiveDeprecated contained spdy_chunk_size -syn keyword ngxDirectiveDeprecated contained spdy_headers_comp -syn keyword ngxDirectiveDeprecated contained spdy_keepalive_timeout -syn keyword ngxDirectiveDeprecated contained spdy_max_concurrent_streams -syn keyword ngxDirectiveDeprecated contained spdy_pool_size -syn keyword ngxDirectiveDeprecated contained spdy_recv_buffer_size -syn keyword ngxDirectiveDeprecated contained spdy_recv_timeout -syn keyword ngxDirectiveDeprecated contained spdy_streams_index_size syn keyword ngxDirectiveDeprecated contained ssl -syn keyword ngxDirectiveDeprecated contained upstream_conf +syn keyword ngxDirectiveDeprecated contained http2_idle_timeout +syn keyword ngxDirectiveDeprecated contained http2_max_field_size +syn keyword ngxDirectiveDeprecated contained http2_max_header_size +syn keyword ngxDirectiveDeprecated contained http2_max_requests +syn keyword ngxDirectiveDeprecated contained http2_recv_timeout syn keyword ngxDirective contained absolute_redirect syn keyword ngxDirective contained accept_mutex @@ -152,6 +147,7 @@ syn keyword ngxDirective contained auth_http_timeout syn keyword ngxDirective contained auth_jwt syn keyword ngxDirective contained auth_jwt_claim_set syn keyword ngxDirective contained auth_jwt_header_set +syn keyword ngxDirective contained auth_jwt_key_cache syn keyword ngxDirective contained auth_jwt_key_file syn keyword ngxDirective contained auth_jwt_key_request syn keyword ngxDirective contained auth_jwt_leeway @@ -309,17 +305,12 @@ syn keyword ngxDirective contained hls_mp4_buffer_size syn keyword ngxDirective contained hls_mp4_max_buffer_size syn keyword ngxDirective contained http2_body_preread_size syn keyword ngxDirective contained http2_chunk_size -syn keyword ngxDirective contained http2_idle_timeout syn keyword ngxDirective contained http2_max_concurrent_pushes syn keyword ngxDirective contained http2_max_concurrent_streams -syn keyword ngxDirective contained http2_max_field_size -syn keyword ngxDirective contained http2_max_header_size -syn keyword ngxDirective contained http2_max_requests syn keyword ngxDirective contained http2_pool_size syn keyword ngxDirective contained http2_push syn keyword ngxDirective contained http2_push_preload syn keyword ngxDirective contained http2_recv_buffer_size -syn keyword ngxDirective contained http2_recv_timeout syn keyword ngxDirective contained http2_streams_index_size syn keyword ngxDirective contained if_modified_since syn keyword ngxDirective contained ignore_invalid_headers @@ -339,14 +330,17 @@ syn keyword ngxDirective contained ip_hash syn keyword ngxDirective contained js_access syn keyword ngxDirective contained js_body_filter syn keyword ngxDirective contained js_content +syn keyword ngxDirective contained js_fetch_buffer_size syn keyword ngxDirective contained js_fetch_ciphers +syn keyword ngxDirective contained js_fetch_max_response_buffer_size syn keyword ngxDirective contained js_fetch_protocols +syn keyword ngxDirective contained js_fetch_timeout syn keyword ngxDirective contained js_fetch_trusted_certificate +syn keyword ngxDirective contained js_fetch_verify syn keyword ngxDirective contained js_fetch_verify_depth syn keyword ngxDirective contained js_filter syn keyword ngxDirective contained js_header_filter syn keyword ngxDirective contained js_import -syn keyword ngxDirective contained js_include syn keyword ngxDirective contained js_path syn keyword ngxDirective contained js_preread syn keyword ngxDirective contained js_set @@ -391,7 +385,6 @@ syn keyword ngxDirective contained max_ranges syn keyword ngxDirective contained memcached_bind syn keyword ngxDirective contained memcached_buffer_size syn keyword ngxDirective contained memcached_connect_timeout -syn keyword ngxDirective contained memcached_force_ranges syn keyword ngxDirective contained memcached_gzip_flag syn keyword ngxDirective contained memcached_next_upstream syn keyword ngxDirective contained memcached_next_upstream_timeout @@ -645,7 +638,6 @@ syn keyword ngxDirective contained status syn keyword ngxDirective contained status_format syn keyword ngxDirective contained status_zone syn keyword ngxDirective contained sticky -syn keyword ngxDirective contained sticky_cookie_insert syn keyword ngxDirective contained stub_status syn keyword ngxDirective contained sub_filter syn keyword ngxDirective contained sub_filter_last_modified @@ -774,62 +766,14 @@ syn keyword ngxDirective contained zone_sync_ssl_verify syn keyword ngxDirective contained zone_sync_ssl_verify_depth syn keyword ngxDirective contained zone_sync_timeout -" 3rd party modules list taken from -" https://github.com/freebsd/freebsd-ports/blob/master/www/nginx-devel/Makefile -" ----------------------------------------------------------------------------- - -" Accept Language -" https://github.com/giom/nginx_accept_language_module -syn keyword ngxDirectiveThirdParty contained set_from_accept_language - -" Digest Authentication -" https://github.com/atomx/nginx-http-auth-digest -syn keyword ngxDirectiveThirdParty contained auth_digest -syn keyword ngxDirectiveThirdParty contained auth_digest_drop_time -syn keyword ngxDirectiveThirdParty contained auth_digest_evasion_time -syn keyword ngxDirectiveThirdParty contained auth_digest_expires -syn keyword ngxDirectiveThirdParty contained auth_digest_maxtries -syn keyword ngxDirectiveThirdParty contained auth_digest_replays -syn keyword ngxDirectiveThirdParty contained auth_digest_shm_size -syn keyword ngxDirectiveThirdParty contained auth_digest_timeout -syn keyword ngxDirectiveThirdParty contained auth_digest_user_file - -" SPNEGO Authentication -" https://github.com/stnoonan/spnego-http-auth-nginx-module -syn keyword ngxDirectiveThirdParty contained auth_gss -syn keyword ngxDirectiveThirdParty contained auth_gss_allow_basic_fallback -syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal -syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal_regex -syn keyword ngxDirectiveThirdParty contained auth_gss_constrained_delegation -syn keyword ngxDirectiveThirdParty contained auth_gss_delegate_credentials -syn keyword ngxDirectiveThirdParty contained auth_gss_force_realm -syn keyword ngxDirectiveThirdParty contained auth_gss_format_full -syn keyword ngxDirectiveThirdParty contained auth_gss_keytab -syn keyword ngxDirectiveThirdParty contained auth_gss_map_to_local -syn keyword ngxDirectiveThirdParty contained auth_gss_realm -syn keyword ngxDirectiveThirdParty contained auth_gss_service_ccache -syn keyword ngxDirectiveThirdParty contained auth_gss_service_name - -" LDAP Authentication -" https://github.com/kvspb/nginx-auth-ldap -syn keyword ngxDirectiveThirdParty contained auth_ldap -syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_enabled -syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_expiration_time -syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_size -syn keyword ngxDirectiveThirdParty contained auth_ldap_servers -syn keyword ngxDirectiveThirdParty contained auth_ldap_servers_size -syn keyword ngxDirectiveThirdParty contained ldap_server -" PAM Authentication -" https://github.com/sto/ngx_http_auth_pam_module -syn keyword ngxDirectiveThirdParty contained auth_pam -syn keyword ngxDirectiveThirdParty contained auth_pam_service_name -syn keyword ngxDirectiveThirdParty contained auth_pam_set_pam_env +" 3rd party modules list taken from +" https://github.com/freebsd/freebsd-ports/blob/main/www/nginx-devel/Makefile.extmod +" ---------------------------------------------------------------------------------- -" AJP protocol proxy -" https://github.com/yaoweibin/nginx_ajp_module -syn keyword ngxDirectiveThirdParty contained ajp_buffers +" https://github.com/msva/nginx_ajp_module syn keyword ngxDirectiveThirdParty contained ajp_buffer_size +syn keyword ngxDirectiveThirdParty contained ajp_buffers syn keyword ngxDirectiveThirdParty contained ajp_busy_buffers_size syn keyword ngxDirectiveThirdParty contained ajp_cache syn keyword ngxDirectiveThirdParty contained ajp_cache_key @@ -850,11 +794,13 @@ syn keyword ngxDirectiveThirdParty contained ajp_keep_conn syn keyword ngxDirectiveThirdParty contained ajp_max_data_packet_size syn keyword ngxDirectiveThirdParty contained ajp_max_temp_file_size syn keyword ngxDirectiveThirdParty contained ajp_next_upstream +syn keyword ngxDirectiveThirdParty contained ajp_param syn keyword ngxDirectiveThirdParty contained ajp_pass syn keyword ngxDirectiveThirdParty contained ajp_pass_header syn keyword ngxDirectiveThirdParty contained ajp_pass_request_body syn keyword ngxDirectiveThirdParty contained ajp_pass_request_headers syn keyword ngxDirectiveThirdParty contained ajp_read_timeout +syn keyword ngxDirectiveThirdParty contained ajp_script_url syn keyword ngxDirectiveThirdParty contained ajp_secret syn keyword ngxDirectiveThirdParty contained ajp_send_lowat syn keyword ngxDirectiveThirdParty contained ajp_send_timeout @@ -865,7 +811,12 @@ syn keyword ngxDirectiveThirdParty contained ajp_temp_path syn keyword ngxDirectiveThirdParty contained ajp_upstream_fail_timeout syn keyword ngxDirectiveThirdParty contained ajp_upstream_max_fails -" AWS proxy +" https://github.com/openresty/array-var-nginx-module +syn keyword ngxDirectiveThirdParty contained array_join +syn keyword ngxDirectiveThirdParty contained array_map +syn keyword ngxDirectiveThirdParty contained array_map_op +syn keyword ngxDirectiveThirdParty contained array_split + " https://github.com/anomalizer/ngx_aws_auth syn keyword ngxDirectiveThirdParty contained aws_access_key syn keyword ngxDirectiveThirdParty contained aws_endpoint @@ -874,7 +825,18 @@ syn keyword ngxDirectiveThirdParty contained aws_s3_bucket syn keyword ngxDirectiveThirdParty contained aws_sign syn keyword ngxDirectiveThirdParty contained aws_signing_key -" embedding Clojure or Java or Groovy programs +" https://github.com/google/ngx_brotli +syn keyword ngxDirectiveThirdParty contained brotli +syn keyword ngxDirectiveThirdParty contained brotli_buffers +syn keyword ngxDirectiveThirdParty contained brotli_comp_level +syn keyword ngxDirectiveThirdParty contained brotli_min_length +syn keyword ngxDirectiveThirdParty contained brotli_static +syn keyword ngxDirectiveThirdParty contained brotli_types +syn keyword ngxDirectiveThirdParty contained brotli_window + +" https://github.com/torden/ngx_cache_purge +syn keyword ngxDirectiveThirdParty contained cache_purge_response_type + " https://github.com/nginx-clojure/nginx-clojure syn keyword ngxDirectiveThirdParty contained access_handler_code syn keyword ngxDirectiveThirdParty contained access_handler_name @@ -892,8 +854,8 @@ syn keyword ngxDirectiveThirdParty contained content_handler_property syn keyword ngxDirectiveThirdParty contained content_handler_type syn keyword ngxDirectiveThirdParty contained handler_code syn keyword ngxDirectiveThirdParty contained handler_name -syn keyword ngxDirectiveThirdParty contained handlers_lazy_init syn keyword ngxDirectiveThirdParty contained handler_type +syn keyword ngxDirectiveThirdParty contained handlers_lazy_init syn keyword ngxDirectiveThirdParty contained header_filter_code syn keyword ngxDirectiveThirdParty contained header_filter_name syn keyword ngxDirectiveThirdParty contained header_filter_property @@ -921,18 +883,20 @@ syn keyword ngxDirectiveThirdParty contained rewrite_handler_type syn keyword ngxDirectiveThirdParty contained shared_map syn keyword ngxDirectiveThirdParty contained write_page_size +" https://github.com/AirisX/nginx_cookie_flag_module +syn keyword ngxDirectiveThirdParty contained set_cookie_flag -" Certificate Transparency " https://github.com/grahamedgecombe/nginx-ct syn keyword ngxDirectiveThirdParty contained ssl_ct syn keyword ngxDirectiveThirdParty contained ssl_ct_static_scts -" ngx_echo " https://github.com/openresty/echo-nginx-module +syn keyword ngxDirectiveThirdParty contained echo syn keyword ngxDirectiveThirdParty contained echo_abort_parent syn keyword ngxDirectiveThirdParty contained echo_after_body syn keyword ngxDirectiveThirdParty contained echo_before_body syn keyword ngxDirectiveThirdParty contained echo_blocking_sleep +syn keyword ngxDirectiveThirdParty contained echo_duplicate syn keyword ngxDirectiveThirdParty contained echo_end syn keyword ngxDirectiveThirdParty contained echo_exec syn keyword ngxDirectiveThirdParty contained echo_flush @@ -942,28 +906,124 @@ syn keyword ngxDirectiveThirdParty contained echo_location_async syn keyword ngxDirectiveThirdParty contained echo_read_request_body syn keyword ngxDirectiveThirdParty contained echo_request_body syn keyword ngxDirectiveThirdParty contained echo_reset_timer +syn keyword ngxDirectiveThirdParty contained echo_sleep syn keyword ngxDirectiveThirdParty contained echo_status syn keyword ngxDirectiveThirdParty contained echo_subrequest syn keyword ngxDirectiveThirdParty contained echo_subrequest_async -" FastDFS -" https://github.com/happyfish100/fastdfs-nginx-module -syn keyword ngxDirectiveThirdParty contained ngx_fastdfs_module +" https://github.com/openresty/drizzle-nginx-module +syn keyword ngxDirectiveThirdParty contained drizzle_buffer_size +syn keyword ngxDirectiveThirdParty contained drizzle_connect_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_dbname +syn keyword ngxDirectiveThirdParty contained drizzle_keepalive +syn keyword ngxDirectiveThirdParty contained drizzle_module_header +syn keyword ngxDirectiveThirdParty contained drizzle_pass +syn keyword ngxDirectiveThirdParty contained drizzle_query +syn keyword ngxDirectiveThirdParty contained drizzle_recv_cols_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_recv_rows_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_send_query_timeout +syn keyword ngxDirectiveThirdParty contained drizzle_server +syn keyword ngxDirectiveThirdParty contained drizzle_status + +" https://github.com/ZigzagAK/ngx_dynamic_upstream +syn keyword ngxDirectiveThirdParty contained dns_add_down +syn keyword ngxDirectiveThirdParty contained dns_ipv6 +syn keyword ngxDirectiveThirdParty contained dns_update +syn keyword ngxDirectiveThirdParty contained dynamic_state_file +syn keyword ngxDirectiveThirdParty contained dynamic_upstream + +" https://github.com/ZigzagAK/ngx_dynamic_healthcheck +syn keyword ngxDirectiveThirdParty contained check +syn keyword ngxDirectiveThirdParty contained check_disable_host +syn keyword ngxDirectiveThirdParty contained check_exclude_host +syn keyword ngxDirectiveThirdParty contained check_persistent +syn keyword ngxDirectiveThirdParty contained check_request_body +syn keyword ngxDirectiveThirdParty contained check_request_headers +syn keyword ngxDirectiveThirdParty contained check_request_uri +syn keyword ngxDirectiveThirdParty contained check_response_body +syn keyword ngxDirectiveThirdParty contained check_response_codes +syn keyword ngxDirectiveThirdParty contained healthcheck +syn keyword ngxDirectiveThirdParty contained healthcheck_buffer_size +syn keyword ngxDirectiveThirdParty contained healthcheck_disable_host +syn keyword ngxDirectiveThirdParty contained healthcheck_get +syn keyword ngxDirectiveThirdParty contained healthcheck_persistent +syn keyword ngxDirectiveThirdParty contained healthcheck_request_body +syn keyword ngxDirectiveThirdParty contained healthcheck_request_headers +syn keyword ngxDirectiveThirdParty contained healthcheck_request_uri +syn keyword ngxDirectiveThirdParty contained healthcheck_response_body +syn keyword ngxDirectiveThirdParty contained healthcheck_response_codes +syn keyword ngxDirectiveThirdParty contained healthcheck_status +syn keyword ngxDirectiveThirdParty contained healthcheck_update + +" https://github.com/openresty/encrypted-session-nginx-module +syn keyword ngxDirectiveThirdParty contained encrypted_session_expires +syn keyword ngxDirectiveThirdParty contained encrypted_session_iv +syn keyword ngxDirectiveThirdParty contained encrypted_session_key +syn keyword ngxDirectiveThirdParty contained set_decrypt_session +syn keyword ngxDirectiveThirdParty contained set_encrypt_session + +" https://github.com/calio/form-input-nginx-module +syn keyword ngxDirectiveThirdParty contained set_form_input +syn keyword ngxDirectiveThirdParty contained set_form_input_multi + +" https://github.com/nieoding/nginx-gridfs +syn keyword ngxDirectiveThirdParty contained gridfs +syn keyword ngxDirectiveThirdParty contained mongo -" ngx_headers_more " https://github.com/openresty/headers-more-nginx-module syn keyword ngxDirectiveThirdParty contained more_clear_headers syn keyword ngxDirectiveThirdParty contained more_clear_input_headers syn keyword ngxDirectiveThirdParty contained more_set_headers syn keyword ngxDirectiveThirdParty contained more_set_input_headers -" NGINX WebDAV missing commands support (PROPFIND & OPTIONS) +" https://github.com/dvershinin/nginx_accept_language_module +syn keyword ngxDirectiveThirdParty contained set_from_accept_language + +" https://github.com/atomx/nginx-http-auth-digest +syn keyword ngxDirectiveThirdParty contained auth_digest +syn keyword ngxDirectiveThirdParty contained auth_digest_drop_time +syn keyword ngxDirectiveThirdParty contained auth_digest_evasion_time +syn keyword ngxDirectiveThirdParty contained auth_digest_expires +syn keyword ngxDirectiveThirdParty contained auth_digest_maxtries +syn keyword ngxDirectiveThirdParty contained auth_digest_replays +syn keyword ngxDirectiveThirdParty contained auth_digest_shm_size +syn keyword ngxDirectiveThirdParty contained auth_digest_timeout +syn keyword ngxDirectiveThirdParty contained auth_digest_user_file + +" https://github.com/stnoonan/spnego-http-auth-nginx-module +syn keyword ngxDirectiveThirdParty contained auth_gss +syn keyword ngxDirectiveThirdParty contained auth_gss_allow_basic_fallback +syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal +syn keyword ngxDirectiveThirdParty contained auth_gss_authorized_principal_regex +syn keyword ngxDirectiveThirdParty contained auth_gss_constrained_delegation +syn keyword ngxDirectiveThirdParty contained auth_gss_delegate_credentials +syn keyword ngxDirectiveThirdParty contained auth_gss_force_realm +syn keyword ngxDirectiveThirdParty contained auth_gss_format_full +syn keyword ngxDirectiveThirdParty contained auth_gss_keytab +syn keyword ngxDirectiveThirdParty contained auth_gss_map_to_local +syn keyword ngxDirectiveThirdParty contained auth_gss_realm +syn keyword ngxDirectiveThirdParty contained auth_gss_service_ccache +syn keyword ngxDirectiveThirdParty contained auth_gss_service_name + +" https://github.com/kvspb/nginx-auth-ldap +syn keyword ngxDirectiveThirdParty contained auth_ldap +syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_enabled +syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_expiration_time +syn keyword ngxDirectiveThirdParty contained auth_ldap_cache_size +syn keyword ngxDirectiveThirdParty contained auth_ldap_servers +syn keyword ngxDirectiveThirdParty contained auth_ldap_servers_size +syn keyword ngxDirectiveThirdParty contained ldap_server + +" https://github.com/sto/ngx_http_auth_pam_module +syn keyword ngxDirectiveThirdParty contained auth_pam +syn keyword ngxDirectiveThirdParty contained auth_pam_service_name +syn keyword ngxDirectiveThirdParty contained auth_pam_set_pam_env + " https://github.com/arut/nginx-dav-ext-module syn keyword ngxDirectiveThirdParty contained dav_ext_lock syn keyword ngxDirectiveThirdParty contained dav_ext_lock_zone syn keyword ngxDirectiveThirdParty contained dav_ext_methods -" ngx_eval " https://github.com/openresty/nginx-eval-module syn keyword ngxDirectiveThirdParty contained eval syn keyword ngxDirectiveThirdParty contained eval_buffer_size @@ -971,7 +1031,6 @@ syn keyword ngxDirectiveThirdParty contained eval_escalate syn keyword ngxDirectiveThirdParty contained eval_override_content_type syn keyword ngxDirectiveThirdParty contained eval_subrequest_in_memory -" Fancy Index " https://github.com/aperezdc/ngx-fancyindex syn keyword ngxDirectiveThirdParty contained fancyindex syn keyword ngxDirectiveThirdParty contained fancyindex_css_href @@ -988,40 +1047,29 @@ syn keyword ngxDirectiveThirdParty contained fancyindex_show_dotfiles syn keyword ngxDirectiveThirdParty contained fancyindex_show_path syn keyword ngxDirectiveThirdParty contained fancyindex_time_format -" Footer filter " https://github.com/alibaba/nginx-http-footer-filter syn keyword ngxDirectiveThirdParty contained footer syn keyword ngxDirectiveThirdParty contained footer_types -" ngx_http_geoip2_module " https://github.com/leev/ngx_http_geoip2_module syn keyword ngxDirectiveThirdParty contained geoip2 syn keyword ngxDirectiveThirdParty contained geoip2_proxy syn keyword ngxDirectiveThirdParty contained geoip2_proxy_recursive -" A version of the Nginx HTTP stub status module that outputs in JSON format -" https://github.com/nginx-modules/nginx-json-status-module -syn keyword ngxDirectiveThirdParty contained json_status -syn keyword ngxDirectiveThirdParty contained json_status_type - -" MogileFS client for nginx -" https://github.com/vkholodkov/nginx-mogilefs-module -syn keyword ngxDirectiveThirdParty contained mogilefs_class -syn keyword ngxDirectiveThirdParty contained mogilefs_connect_timeout -syn keyword ngxDirectiveThirdParty contained mogilefs_domain -syn keyword ngxDirectiveThirdParty contained mogilefs_methods -syn keyword ngxDirectiveThirdParty contained mogilefs_noverify -syn keyword ngxDirectiveThirdParty contained mogilefs_pass -syn keyword ngxDirectiveThirdParty contained mogilefs_read_timeout -syn keyword ngxDirectiveThirdParty contained mogilefs_send_timeout -syn keyword ngxDirectiveThirdParty contained mogilefs_tracker - -" Ancient nginx plugin; probably not useful to anyone +" https://github.com/ip2location/ip2location-nginx +syn keyword ngxDirectiveThirdParty contained ip2location_database +syn keyword ngxDirectiveThirdParty contained ip2location_proxy +syn keyword ngxDirectiveThirdParty contained ip2location_proxy_recursive + +" https://github.com/ip2location/ip2proxy-nginx +syn keyword ngxDirectiveThirdParty contained ip2proxy_database +syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy +syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_recursive + " https://github.com/kr/nginx-notice syn keyword ngxDirectiveThirdParty contained notice syn keyword ngxDirectiveThirdParty contained notice_type -" nchan " https://github.com/slact/nchan syn keyword ngxDirectiveThirdParty contained nchan_access_control_allow_credentials syn keyword ngxDirectiveThirdParty contained nchan_access_control_allow_origin @@ -1034,8 +1082,8 @@ syn keyword ngxDirectiveThirdParty contained nchan_benchmark_publisher_distribut syn keyword ngxDirectiveThirdParty contained nchan_benchmark_subscriber_distribution syn keyword ngxDirectiveThirdParty contained nchan_benchmark_subscribers_per_channel syn keyword ngxDirectiveThirdParty contained nchan_benchmark_time -syn keyword ngxDirectiveThirdParty contained nchan_channel_events_channel_id syn keyword ngxDirectiveThirdParty contained nchan_channel_event_string +syn keyword ngxDirectiveThirdParty contained nchan_channel_events_channel_id syn keyword ngxDirectiveThirdParty contained nchan_channel_group syn keyword ngxDirectiveThirdParty contained nchan_channel_group_accounting syn keyword ngxDirectiveThirdParty contained nchan_channel_id @@ -1074,11 +1122,25 @@ syn keyword ngxDirectiveThirdParty contained nchan_pubsub syn keyword ngxDirectiveThirdParty contained nchan_pubsub_channel_id syn keyword ngxDirectiveThirdParty contained nchan_pubsub_location syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_backoff +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_jitter +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_max +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_check_interval_min +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_connect_timeout +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_max_failing_time +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_backoff +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_jitter +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_max +syn keyword ngxDirectiveThirdParty contained nchan_redis_cluster_recovery_delay_min +syn keyword ngxDirectiveThirdParty contained nchan_redis_command_timeout syn keyword ngxDirectiveThirdParty contained nchan_redis_connect_timeout syn keyword ngxDirectiveThirdParty contained nchan_redis_discovered_ip_range_blacklist syn keyword ngxDirectiveThirdParty contained nchan_redis_fakesub_timer_interval syn keyword ngxDirectiveThirdParty contained nchan_redis_idle_channel_cache_timeout +syn keyword ngxDirectiveThirdParty contained nchan_redis_load_scripts_unconditionally syn keyword ngxDirectiveThirdParty contained nchan_redis_namespace +syn keyword ngxDirectiveThirdParty contained nchan_redis_node_connect_timeout syn keyword ngxDirectiveThirdParty contained nchan_redis_nostore_fastpublish syn keyword ngxDirectiveThirdParty contained nchan_redis_optimize_target syn keyword ngxDirectiveThirdParty contained nchan_redis_pass @@ -1086,6 +1148,13 @@ syn keyword ngxDirectiveThirdParty contained nchan_redis_pass_inheritable syn keyword ngxDirectiveThirdParty contained nchan_redis_password syn keyword ngxDirectiveThirdParty contained nchan_redis_ping_interval syn keyword ngxDirectiveThirdParty contained nchan_redis_publish_msgpacked_max_size +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_backoff +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_jitter +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_max +syn keyword ngxDirectiveThirdParty contained nchan_redis_reconnect_delay_min +syn keyword ngxDirectiveThirdParty contained nchan_redis_retry_commands +syn keyword ngxDirectiveThirdParty contained nchan_redis_retry_commands_max_wait syn keyword ngxDirectiveThirdParty contained nchan_redis_server syn keyword ngxDirectiveThirdParty contained nchan_redis_ssl syn keyword ngxDirectiveThirdParty contained nchan_redis_ssl_ciphers @@ -1113,10 +1182,10 @@ syn keyword ngxDirectiveThirdParty contained nchan_store_messages syn keyword ngxDirectiveThirdParty contained nchan_stub_status syn keyword ngxDirectiveThirdParty contained nchan_sub_channel_id syn keyword ngxDirectiveThirdParty contained nchan_subscribe_existing_channels_only +syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request syn keyword ngxDirectiveThirdParty contained nchan_subscriber syn keyword ngxDirectiveThirdParty contained nchan_subscriber_channel_id syn keyword ngxDirectiveThirdParty contained nchan_subscriber_compound_etag_message_id -syn keyword ngxDirectiveThirdParty contained nchan_subscribe_request syn keyword ngxDirectiveThirdParty contained nchan_subscriber_first_message syn keyword ngxDirectiveThirdParty contained nchan_subscriber_http_raw_stream_separator syn keyword ngxDirectiveThirdParty contained nchan_subscriber_info @@ -1145,7 +1214,6 @@ syn keyword ngxDirectiveThirdParty contained push_subscriber syn keyword ngxDirectiveThirdParty contained push_subscriber_concurrency syn keyword ngxDirectiveThirdParty contained push_subscriber_timeout -" Push Stream " https://github.com/wandenberg/nginx-push-stream-module syn keyword ngxDirectiveThirdParty contained push_stream_allow_connections_to_events_channel syn keyword ngxDirectiveThirdParty contained push_stream_allowed_origins @@ -1184,23 +1252,6 @@ syn keyword ngxDirectiveThirdParty contained push_stream_websocket_allow_publish syn keyword ngxDirectiveThirdParty contained push_stream_wildcard_channel_max_qtd syn keyword ngxDirectiveThirdParty contained push_stream_wildcard_channel_prefix -" redis module -" https://www.nginx.com/resources/wiki/modules/redis/ -syn keyword ngxDirectiveThirdParty contained redis_bind -syn keyword ngxDirectiveThirdParty contained redis_buffer_size -syn keyword ngxDirectiveThirdParty contained redis_connect_timeout -syn keyword ngxDirectiveThirdParty contained redis_gzip_flag -syn keyword ngxDirectiveThirdParty contained redis_next_upstream -syn keyword ngxDirectiveThirdParty contained redis_pass -syn keyword ngxDirectiveThirdParty contained redis_read_timeout -syn keyword ngxDirectiveThirdParty contained redis_send_timeout - -" ngx_http_response -" http://catap.ru/downloads/nginx/ -syn keyword ngxDirectiveThirdParty contained response -syn keyword ngxDirectiveThirdParty contained response_type - -" nginx_substitutions_filter " https://github.com/yaoweibin/ngx_http_substitutions_filter_module syn keyword ngxDirectiveThirdParty contained subs_buffers syn keyword ngxDirectiveThirdParty contained subs_filter @@ -1208,7 +1259,6 @@ syn keyword ngxDirectiveThirdParty contained subs_filter_bypass syn keyword ngxDirectiveThirdParty contained subs_filter_types syn keyword ngxDirectiveThirdParty contained subs_line_buffer_size -" Tarantool nginx upstream module " https://github.com/tarantool/nginx_upstream_module syn keyword ngxDirectiveThirdParty contained tnt_allowed_indexes syn keyword ngxDirectiveThirdParty contained tnt_allowed_spaces @@ -1238,44 +1288,28 @@ syn keyword ngxDirectiveThirdParty contained tnt_set_header syn keyword ngxDirectiveThirdParty contained tnt_update syn keyword ngxDirectiveThirdParty contained tnt_upsert -" A module for nginx web server for handling file uploads using multipart/form-data encoding (RFC 1867) -" https://github.com/Austinb/nginx-upload-module +" https://github.com/fdintino/nginx-upload-module +syn keyword ngxDirectiveThirdParty contained upload_add_header syn keyword ngxDirectiveThirdParty contained upload_aggregate_form_field -syn keyword ngxDirectiveThirdParty contained upload_archive_elm -syn keyword ngxDirectiveThirdParty contained upload_archive_elm_separator -syn keyword ngxDirectiveThirdParty contained upload_archive_path -syn keyword ngxDirectiveThirdParty contained upload_archive_path_separator syn keyword ngxDirectiveThirdParty contained upload_buffer_size syn keyword ngxDirectiveThirdParty contained upload_cleanup -syn keyword ngxDirectiveThirdParty contained upload_content_type -syn keyword ngxDirectiveThirdParty contained upload_discard -syn keyword ngxDirectiveThirdParty contained upload_field_name -syn keyword ngxDirectiveThirdParty contained upload_file_crc32 -syn keyword ngxDirectiveThirdParty contained upload_file_md5 -syn keyword ngxDirectiveThirdParty contained upload_file_md5_uc -syn keyword ngxDirectiveThirdParty contained upload_file_name -syn keyword ngxDirectiveThirdParty contained upload_file_sha1 -syn keyword ngxDirectiveThirdParty contained upload_file_sha1_uc -syn keyword ngxDirectiveThirdParty contained upload_file_size -syn keyword ngxDirectiveThirdParty contained upload_filter +syn keyword ngxDirectiveThirdParty contained upload_empty_fiels_names +syn keyword ngxDirectiveThirdParty contained upload_limit_rate syn keyword ngxDirectiveThirdParty contained upload_max_file_size syn keyword ngxDirectiveThirdParty contained upload_max_output_body_len syn keyword ngxDirectiveThirdParty contained upload_max_part_header_len +syn keyword ngxDirectiveThirdParty contained upload_merge_buffer_size syn keyword ngxDirectiveThirdParty contained upload_pass syn keyword ngxDirectiveThirdParty contained upload_pass_args syn keyword ngxDirectiveThirdParty contained upload_pass_form_field +syn keyword ngxDirectiveThirdParty contained upload_range_header_buffer_size +syn keyword ngxDirectiveThirdParty contained upload_resumable syn keyword ngxDirectiveThirdParty contained upload_set_form_field +syn keyword ngxDirectiveThirdParty contained upload_state_store syn keyword ngxDirectiveThirdParty contained upload_store syn keyword ngxDirectiveThirdParty contained upload_store_access -syn keyword ngxDirectiveThirdParty contained upload_tmp_path -syn keyword ngxDirectiveThirdParty contained upload_unzip -syn keyword ngxDirectiveThirdParty contained upload_unzip_buffers -syn keyword ngxDirectiveThirdParty contained upload_unzip_hash -syn keyword ngxDirectiveThirdParty contained upload_unzip_max_file_name_len -syn keyword ngxDirectiveThirdParty contained upload_unzip_window -syn keyword ngxDirectiveThirdParty contained upload_void_content_type - -" nginx-upload-progress-module +syn keyword ngxDirectiveThirdParty contained upload_tame_arrays + " https://github.com/masterzen/nginx-upload-progress-module syn keyword ngxDirectiveThirdParty contained report_uploads syn keyword ngxDirectiveThirdParty contained track_uploads @@ -1288,9 +1322,7 @@ syn keyword ngxDirectiveThirdParty contained upload_progress_jsonp_output syn keyword ngxDirectiveThirdParty contained upload_progress_jsonp_parameter syn keyword ngxDirectiveThirdParty contained upload_progress_template -" Health checks upstreams for nginx " https://github.com/yaoweibin/nginx_upstream_check_module -syn keyword ngxDirectiveThirdParty contained check syn keyword ngxDirectiveThirdParty contained check_fastcgi_param syn keyword ngxDirectiveThirdParty contained check_http_expect_alive syn keyword ngxDirectiveThirdParty contained check_http_send @@ -1298,13 +1330,14 @@ syn keyword ngxDirectiveThirdParty contained check_keepalive_requests syn keyword ngxDirectiveThirdParty contained check_shm_size syn keyword ngxDirectiveThirdParty contained check_status -" The fair load balancer module for nginx -" https://github.com/cryptofuture/nginx-upstream-fair +" https://github.com/jaygooby/nginx-upstream-fair syn keyword ngxDirectiveThirdParty contained fair syn keyword ngxDirectiveThirdParty contained upstream_fair_shm_size -" Nginx Video Thumb Extractor Module -" https://github.com/wandenberg/nginx-video-thumbextractor-module +" https://github.com/ayty-adrianomartins/nginx-sticky-module-ng +syn keyword ngxDirectiveThirdParty contained sticky_no_fallback + +" https://github.com/Novetta/nginx-video-thumbextractor-module syn keyword ngxDirectiveThirdParty contained video_thumbextractor syn keyword ngxDirectiveThirdParty contained video_thumbextractor_image_height syn keyword ngxDirectiveThirdParty contained video_thumbextractor_image_width @@ -1329,43 +1362,14 @@ syn keyword ngxDirectiveThirdParty contained video_thumbextractor_tile_sample_in syn keyword ngxDirectiveThirdParty contained video_thumbextractor_video_filename syn keyword ngxDirectiveThirdParty contained video_thumbextractor_video_second -" drizzle-nginx-module - Upstream module for talking to MySQL and Drizzle directly -" https://github.com/openresty/drizzle-nginx-module -syn keyword ngxDirectiveThirdParty contained drizzle_buffer_size -syn keyword ngxDirectiveThirdParty contained drizzle_connect_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_dbname -syn keyword ngxDirectiveThirdParty contained drizzle_keepalive -syn keyword ngxDirectiveThirdParty contained drizzle_module_header -syn keyword ngxDirectiveThirdParty contained drizzle_pass -syn keyword ngxDirectiveThirdParty contained drizzle_query -syn keyword ngxDirectiveThirdParty contained drizzle_recv_cols_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_recv_rows_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_send_query_timeout -syn keyword ngxDirectiveThirdParty contained drizzle_server -syn keyword ngxDirectiveThirdParty contained drizzle_status - -" ngx_dynamic_upstream -" https://github.com/cubicdaiya/ngx_dynamic_upstream -syn keyword ngxDirectiveThirdParty contained dynamic_upstream - -" encrypt and decrypt nginx variable values -" https://github.com/openresty/encrypted-session-nginx-module -syn keyword ngxDirectiveThirdParty contained encrypted_session_expires -syn keyword ngxDirectiveThirdParty contained encrypted_session_iv -syn keyword ngxDirectiveThirdParty contained encrypted_session_key -syn keyword ngxDirectiveThirdParty contained set_decrypt_session -syn keyword ngxDirectiveThirdParty contained set_encrypt_session - -" serve content directly from MongoDB's GridFS -" https://github.com/mdirolf/nginx-gridfs -syn keyword ngxDirectiveThirdParty contained gridfs -syn keyword ngxDirectiveThirdParty contained mongo +" https://github.com/calio/iconv-nginx-module +syn keyword ngxDirectiveThirdParty contained iconv_buffer_size +syn keyword ngxDirectiveThirdParty contained iconv_filter +syn keyword ngxDirectiveThirdParty contained set_iconv -" Adds support for arithmetic operations to NGINX config -" https://github.com/arut/nginx-let-module +" https://github.com/baysao/nginx-let-module syn keyword ngxDirectiveThirdParty contained let -" ngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers " https://github.com/openresty/lua-nginx-module syn keyword ngxDirectiveThirdParty contained access_by_lua syn keyword ngxDirectiveThirdParty contained access_by_lua_block @@ -1431,6 +1435,8 @@ syn keyword ngxDirectiveThirdParty contained rewrite_by_lua syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_block syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_file syn keyword ngxDirectiveThirdParty contained rewrite_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty contained server_rewrite_by_lua_block +syn keyword ngxDirectiveThirdParty contained server_rewrite_by_lua_file syn keyword ngxDirectiveThirdParty contained set_by_lua syn keyword ngxDirectiveThirdParty contained set_by_lua_block syn keyword ngxDirectiveThirdParty contained set_by_lua_file @@ -1443,7 +1449,16 @@ syn keyword ngxDirectiveThirdParty contained ssl_session_fetch_by_lua_file syn keyword ngxDirectiveThirdParty contained ssl_session_store_by_lua_block syn keyword ngxDirectiveThirdParty contained ssl_session_store_by_lua_file -" ngx_memc - An extended version of the standard memcached module +" https://github.com/Taymindis/nginx-link-function +syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_prop +syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_req_header +syn keyword ngxDirectiveThirdParty contained ngx_link_func_ca_cert +syn keyword ngxDirectiveThirdParty contained ngx_link_func_call +syn keyword ngxDirectiveThirdParty contained ngx_link_func_download_link_lib +syn keyword ngxDirectiveThirdParty contained ngx_link_func_lib +syn keyword ngxDirectiveThirdParty contained ngx_link_func_shm_size +syn keyword ngxDirectiveThirdParty contained ngx_link_func_subrequest + " https://github.com/openresty/memc-nginx-module syn keyword ngxDirectiveThirdParty contained memc_buffer_size syn keyword ngxDirectiveThirdParty contained memc_cmds_allowed @@ -1457,21 +1472,24 @@ syn keyword ngxDirectiveThirdParty contained memc_send_timeout syn keyword ngxDirectiveThirdParty contained memc_upstream_fail_timeout syn keyword ngxDirectiveThirdParty contained memc_upstream_max_fails -" ModSecurity web application firewall -" https://github.com/SpiderLabs/ModSecurity/tree/master -syn keyword ngxDirectiveThirdParty contained ModSecurityConfig -syn keyword ngxDirectiveThirdParty contained ModSecurityEnabled -syn keyword ngxDirectiveThirdParty contained pool_context_hash_size +" https://github.com/SpiderLabs/ModSecurity-nginx +syn keyword ngxDirectiveThirdParty contained modsecurity +syn keyword ngxDirectiveThirdParty contained modsecurity_rules +syn keyword ngxDirectiveThirdParty contained modsecurity_rules_file +syn keyword ngxDirectiveThirdParty contained modsecurity_rules_remote +syn keyword ngxDirectiveThirdParty contained modsecurity_transaction_id -" NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX " https://github.com/nbs-system/naxsi syn keyword ngxDirectiveThirdParty contained BasicRule syn keyword ngxDirectiveThirdParty contained CheckRule syn keyword ngxDirectiveThirdParty contained DeniedUrl +syn keyword ngxDirectiveThirdParty contained IgnoreCIDR +syn keyword ngxDirectiveThirdParty contained IgnoreIP syn keyword ngxDirectiveThirdParty contained LearningMode syn keyword ngxDirectiveThirdParty contained LibInjectionSql syn keyword ngxDirectiveThirdParty contained LibInjectionXss syn keyword ngxDirectiveThirdParty contained MainRule +syn keyword ngxDirectiveThirdParty contained NaxsiLogFile syn keyword ngxDirectiveThirdParty contained SecRulesDisabled syn keyword ngxDirectiveThirdParty contained SecRulesEnabled syn keyword ngxDirectiveThirdParty contained basic_rule @@ -1481,17 +1499,31 @@ syn keyword ngxDirectiveThirdParty contained learning_mode syn keyword ngxDirectiveThirdParty contained libinjection_sql syn keyword ngxDirectiveThirdParty contained libinjection_xss syn keyword ngxDirectiveThirdParty contained main_rule +syn keyword ngxDirectiveThirdParty contained naxsi_log syn keyword ngxDirectiveThirdParty contained rules_disabled syn keyword ngxDirectiveThirdParty contained rules_enabled -" Phusion Passenger -" https://www.phusionpassenger.com/library/config/nginx/reference/ +" https://github.com/opentracing-contrib/nginx-opentracing +syn keyword ngxDirectiveThirdParty contained opentracing +syn keyword ngxDirectiveThirdParty contained opentracing_fastcgi_propagate_context +syn keyword ngxDirectiveThirdParty contained opentracing_grpc_propagate_context +syn keyword ngxDirectiveThirdParty contained opentracing_load_tracer +syn keyword ngxDirectiveThirdParty contained opentracing_location_operation_name +syn keyword ngxDirectiveThirdParty contained opentracing_operation_name +syn keyword ngxDirectiveThirdParty contained opentracing_propagate_context +syn keyword ngxDirectiveThirdParty contained opentracing_tag +syn keyword ngxDirectiveThirdParty contained opentracing_trace_locations +syn keyword ngxDirectiveThirdParty contained opentracing_trust_incoming_span + +" https://github.com/phusion/passenger syn keyword ngxDirectiveThirdParty contained passenger_abort_on_startup_error syn keyword ngxDirectiveThirdParty contained passenger_abort_websockets_on_process_shutdown syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_auth_type syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_password syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_url syn keyword ngxDirectiveThirdParty contained passenger_admin_panel_username +syn keyword ngxDirectiveThirdParty contained passenger_analytics_log_group +syn keyword ngxDirectiveThirdParty contained passenger_analytics_log_user syn keyword ngxDirectiveThirdParty contained passenger_anonymous_telemetry_proxy syn keyword ngxDirectiveThirdParty contained passenger_app_env syn keyword ngxDirectiveThirdParty contained passenger_app_file_descriptor_ulimit @@ -1499,20 +1531,25 @@ syn keyword ngxDirectiveThirdParty contained passenger_app_group_name syn keyword ngxDirectiveThirdParty contained passenger_app_log_file syn keyword ngxDirectiveThirdParty contained passenger_app_rights syn keyword ngxDirectiveThirdParty contained passenger_app_root +syn keyword ngxDirectiveThirdParty contained passenger_app_start_command syn keyword ngxDirectiveThirdParty contained passenger_app_type syn keyword ngxDirectiveThirdParty contained passenger_base_uri syn keyword ngxDirectiveThirdParty contained passenger_buffer_response syn keyword ngxDirectiveThirdParty contained passenger_buffer_size +syn keyword ngxDirectiveThirdParty contained passenger_buffer_upload syn keyword ngxDirectiveThirdParty contained passenger_buffers syn keyword ngxDirectiveThirdParty contained passenger_busy_buffers_size syn keyword ngxDirectiveThirdParty contained passenger_concurrency_model syn keyword ngxDirectiveThirdParty contained passenger_core_file_descriptor_ulimit syn keyword ngxDirectiveThirdParty contained passenger_ctl syn keyword ngxDirectiveThirdParty contained passenger_data_buffer_dir +syn keyword ngxDirectiveThirdParty contained passenger_debug_log_file syn keyword ngxDirectiveThirdParty contained passenger_debugger syn keyword ngxDirectiveThirdParty contained passenger_default_group syn keyword ngxDirectiveThirdParty contained passenger_default_user +syn keyword ngxDirectiveThirdParty contained passenger_direct_instance_request_address syn keyword ngxDirectiveThirdParty contained passenger_disable_anonymous_telemetry +syn keyword ngxDirectiveThirdParty contained passenger_disable_log_prefix syn keyword ngxDirectiveThirdParty contained passenger_disable_security_update_check syn keyword ngxDirectiveThirdParty contained passenger_document_root syn keyword ngxDirectiveThirdParty contained passenger_dump_config_manifest @@ -1548,8 +1585,10 @@ syn keyword ngxDirectiveThirdParty contained passenger_nodejs syn keyword ngxDirectiveThirdParty contained passenger_pass_header syn keyword ngxDirectiveThirdParty contained passenger_pool_idle_time syn keyword ngxDirectiveThirdParty contained passenger_pre_start +syn keyword ngxDirectiveThirdParty contained passenger_preload_bundler syn keyword ngxDirectiveThirdParty contained passenger_python syn keyword ngxDirectiveThirdParty contained passenger_read_timeout +syn keyword ngxDirectiveThirdParty contained passenger_request_buffering syn keyword ngxDirectiveThirdParty contained passenger_request_queue_overflow_status_code syn keyword ngxDirectiveThirdParty contained passenger_resist_deployment_errors syn keyword ngxDirectiveThirdParty contained passenger_response_buffer_high_watermark @@ -1561,36 +1600,36 @@ syn keyword ngxDirectiveThirdParty contained passenger_security_update_check_pro syn keyword ngxDirectiveThirdParty contained passenger_set_header syn keyword ngxDirectiveThirdParty contained passenger_show_version_in_header syn keyword ngxDirectiveThirdParty contained passenger_socket_backlog +syn keyword ngxDirectiveThirdParty contained passenger_spawn_dir +syn keyword ngxDirectiveThirdParty contained passenger_spawn_exception_status_code syn keyword ngxDirectiveThirdParty contained passenger_spawn_method syn keyword ngxDirectiveThirdParty contained passenger_start_timeout syn keyword ngxDirectiveThirdParty contained passenger_startup_file syn keyword ngxDirectiveThirdParty contained passenger_stat_throttle_rate syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions +syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions_cookie_attributes syn keyword ngxDirectiveThirdParty contained passenger_sticky_sessions_cookie_name +syn keyword ngxDirectiveThirdParty contained passenger_temp_path syn keyword ngxDirectiveThirdParty contained passenger_thread_count syn keyword ngxDirectiveThirdParty contained passenger_turbocaching +syn keyword ngxDirectiveThirdParty contained passenger_use_global_queue syn keyword ngxDirectiveThirdParty contained passenger_user syn keyword ngxDirectiveThirdParty contained passenger_user_switching syn keyword ngxDirectiveThirdParty contained passenger_vary_turbocache_by_cookie -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_analytics_log_group -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_analytics_log_user -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_debug_log_file -syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_use_global_queue -syn keyword ngxDirectiveThirdPartyDeprecated contained rack_env -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_app_spawner_idle_time -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_env -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_framework_spawner_idle_time -syn keyword ngxDirectiveThirdPartyDeprecated contained rails_spawn_method -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_filter -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_address -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_cert -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_port -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_key -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_proxy_address -syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_support - -" ngx_postgres is an upstream module that allows nginx to communicate directly with PostgreSQL database -" https://github.com/FRiCKLE/ngx_postgres +syn keyword ngxDirectiveThirdParty contained rack_env +syn keyword ngxDirectiveThirdParty contained rails_app_spawner_idle_time +syn keyword ngxDirectiveThirdParty contained rails_env +syn keyword ngxDirectiveThirdParty contained rails_framework_spawner_idle_time +syn keyword ngxDirectiveThirdParty contained rails_spawn_method +syn keyword ngxDirectiveThirdParty contained union_station_filter +syn keyword ngxDirectiveThirdParty contained union_station_gateway_address +syn keyword ngxDirectiveThirdParty contained union_station_gateway_cert +syn keyword ngxDirectiveThirdParty contained union_station_gateway_port +syn keyword ngxDirectiveThirdParty contained union_station_key +syn keyword ngxDirectiveThirdParty contained union_station_proxy_address +syn keyword ngxDirectiveThirdParty contained union_station_support + +" https://github.com/konstruxi/ngx_postgres syn keyword ngxDirectiveThirdParty contained postgres_connect_timeout syn keyword ngxDirectiveThirdParty contained postgres_escape syn keyword ngxDirectiveThirdParty contained postgres_keepalive @@ -1602,7 +1641,6 @@ syn keyword ngxDirectiveThirdParty contained postgres_rewrite syn keyword ngxDirectiveThirdParty contained postgres_server syn keyword ngxDirectiveThirdParty contained postgres_set -" ngx_rds_csv - Nginx output filter module to convert Resty-DBD-Streams (RDS) to Comma-Separated Values (CSV) " https://github.com/openresty/rds-csv-nginx-module syn keyword ngxDirectiveThirdParty contained rds_csv syn keyword ngxDirectiveThirdParty contained rds_csv_buffer_size @@ -1611,7 +1649,6 @@ syn keyword ngxDirectiveThirdParty contained rds_csv_field_name_header syn keyword ngxDirectiveThirdParty contained rds_csv_field_separator syn keyword ngxDirectiveThirdParty contained rds_csv_row_terminator -" ngx_rds_json - an output filter that formats Resty DBD Streams generated by ngx_drizzle and others to JSON " https://github.com/openresty/rds-json-nginx-module syn keyword ngxDirectiveThirdParty contained rds_json syn keyword ngxDirectiveThirdParty contained rds_json_buffer_size @@ -1624,7 +1661,6 @@ syn keyword ngxDirectiveThirdParty contained rds_json_root syn keyword ngxDirectiveThirdParty contained rds_json_success_property syn keyword ngxDirectiveThirdParty contained rds_json_user_property -" ngx_redis2 - Nginx upstream module for the Redis 2.0 protocol " https://github.com/openresty/redis2-nginx-module syn keyword ngxDirectiveThirdParty contained redis2_bind syn keyword ngxDirectiveThirdParty contained redis2_buffer_size @@ -1638,7 +1674,6 @@ syn keyword ngxDirectiveThirdParty contained redis2_raw_query syn keyword ngxDirectiveThirdParty contained redis2_read_timeout syn keyword ngxDirectiveThirdParty contained redis2_send_timeout -" NGINX-based Media Streaming Server " https://github.com/arut/nginx-rtmp-module syn keyword ngxDirectiveThirdParty contained ack_window syn keyword ngxDirectiveThirdParty contained application @@ -1750,7 +1785,6 @@ syn keyword ngxDirectiveThirdParty contained sync syn keyword ngxDirectiveThirdParty contained wait_key syn keyword ngxDirectiveThirdParty contained wait_video -" ngx_set_misc - Various set_xxx directives added to nginx's rewrite module (md5/sha1, sql/json quoting, and many more) " https://github.com/openresty/set-misc-nginx-module syn keyword ngxDirectiveThirdParty contained set_base32_alphabet syn keyword ngxDirectiveThirdParty contained set_base32_padding @@ -1770,6 +1804,7 @@ syn keyword ngxDirectiveThirdParty contained set_hmac_sha1 syn keyword ngxDirectiveThirdParty contained set_hmac_sha256 syn keyword ngxDirectiveThirdParty contained set_if_empty syn keyword ngxDirectiveThirdParty contained set_local_today +syn keyword ngxDirectiveThirdParty contained set_md5 syn keyword ngxDirectiveThirdParty contained set_misc_base32_padding syn keyword ngxDirectiveThirdParty contained set_quote_json_str syn keyword ngxDirectiveThirdParty contained set_quote_pgsql_str @@ -1778,20 +1813,18 @@ syn keyword ngxDirectiveThirdParty contained set_random syn keyword ngxDirectiveThirdParty contained set_rotate syn keyword ngxDirectiveThirdParty contained set_secure_random_alphanum syn keyword ngxDirectiveThirdParty contained set_secure_random_lcalpha +syn keyword ngxDirectiveThirdParty contained set_sha1 syn keyword ngxDirectiveThirdParty contained set_unescape_uri -" nginx-sflow-module " https://github.com/sflow/nginx-sflow-module syn keyword ngxDirectiveThirdParty contained sflow -" Shibboleth auth request module for Nginx " https://github.com/nginx-shib/nginx-http-shibboleth syn keyword ngxDirectiveThirdParty contained shib_request syn keyword ngxDirectiveThirdParty contained shib_request_set syn keyword ngxDirectiveThirdParty contained shib_request_use_headers -" nginx module which adds ability to cache static files -" https://github.com/FRiCKLE/ngx_slowfs_cache +" https://github.com/baysao/ngx_slowfs_cache syn keyword ngxDirectiveThirdParty contained slowfs_big_file_size syn keyword ngxDirectiveThirdParty contained slowfs_cache syn keyword ngxDirectiveThirdParty contained slowfs_cache_key @@ -1801,8 +1834,7 @@ syn keyword ngxDirectiveThirdParty contained slowfs_cache_purge syn keyword ngxDirectiveThirdParty contained slowfs_cache_valid syn keyword ngxDirectiveThirdParty contained slowfs_temp_path -" Dynamic Image Transformation Module For nginx -" https://github.com/cubicdaiya/ngx_small_light +" https://github.com/kawakibi/ngx_small_light syn keyword ngxDirectiveThirdParty contained small_light syn keyword ngxDirectiveThirdParty contained small_light_buffer syn keyword ngxDirectiveThirdParty contained small_light_getparam_mode @@ -1812,7 +1844,6 @@ syn keyword ngxDirectiveThirdParty contained small_light_pattern_define syn keyword ngxDirectiveThirdParty contained small_light_radius_max syn keyword ngxDirectiveThirdParty contained small_light_sigma_max -" ngx_srcache - Transparent subrequest-based caching layout for arbitrary nginx locations " https://github.com/openresty/srcache-nginx-module syn keyword ngxDirectiveThirdParty contained srcache_buffer syn keyword ngxDirectiveThirdParty contained srcache_default_expire @@ -1835,7 +1866,6 @@ syn keyword ngxDirectiveThirdParty contained srcache_store_ranges syn keyword ngxDirectiveThirdParty contained srcache_store_skip syn keyword ngxDirectiveThirdParty contained srcache_store_statuses -" NGINX-based VOD Packager " https://github.com/kaltura/nginx-vod-module syn keyword ngxDirectiveThirdParty contained vod syn keyword ngxDirectiveThirdParty contained vod_align_segments_to_key_frames @@ -1875,6 +1905,7 @@ syn keyword ngxDirectiveThirdParty contained vod_live_window_duration syn keyword ngxDirectiveThirdParty contained vod_manifest_duration_policy syn keyword ngxDirectiveThirdParty contained vod_manifest_segment_durations_mode syn keyword ngxDirectiveThirdParty contained vod_mapping_cache +syn keyword ngxDirectiveThirdParty contained vod_max_frame_count syn keyword ngxDirectiveThirdParty contained vod_max_frames_size syn keyword ngxDirectiveThirdParty contained vod_max_mapping_response_size syn keyword ngxDirectiveThirdParty contained vod_max_metadata_size @@ -1901,6 +1932,7 @@ syn keyword ngxDirectiveThirdParty contained vod_response_cache syn keyword ngxDirectiveThirdParty contained vod_secret_key syn keyword ngxDirectiveThirdParty contained vod_segment_count_policy syn keyword ngxDirectiveThirdParty contained vod_segment_duration +syn keyword ngxDirectiveThirdParty contained vod_segment_max_frame_count syn keyword ngxDirectiveThirdParty contained vod_segments_base_url syn keyword ngxDirectiveThirdParty contained vod_source_clip_map_uri syn keyword ngxDirectiveThirdParty contained vod_speed_param_name @@ -1910,7 +1942,6 @@ syn keyword ngxDirectiveThirdParty contained vod_tracks_param_name syn keyword ngxDirectiveThirdParty contained vod_upstream_extra_args syn keyword ngxDirectiveThirdParty contained vod_upstream_location -" Nginx virtual host traffic status module " https://github.com/vozlt/nginx-module-vts syn keyword ngxDirectiveThirdParty contained vhost_traffic_status syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_average_method @@ -1934,7 +1965,6 @@ syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_limit_traffic_ syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_set_by_filter syn keyword ngxDirectiveThirdParty contained vhost_traffic_status_zone -" xss-nginx-module - Native cross-site scripting support in nginx " https://github.com/openresty/xss-nginx-module syn keyword ngxDirectiveThirdParty contained xss_callback_arg syn keyword ngxDirectiveThirdParty contained xss_check_status @@ -1943,471 +1973,6 @@ syn keyword ngxDirectiveThirdParty contained xss_input_types syn keyword ngxDirectiveThirdParty contained xss_output_type syn keyword ngxDirectiveThirdParty contained xss_override_status -" Add support for array-typed variables to nginx config files -" https://github.com/openresty/array-var-nginx-module -syn keyword ngxDirectiveThirdParty contained array_join -syn keyword ngxDirectiveThirdParty contained array_map -syn keyword ngxDirectiveThirdParty contained array_map_op -syn keyword ngxDirectiveThirdParty contained array_split - -" NGINX module for Brotli compression -" https://github.com/eustas/ngx_brotli -syn keyword ngxDirectiveThirdParty contained brotli -syn keyword ngxDirectiveThirdParty contained brotli_buffers -syn keyword ngxDirectiveThirdParty contained brotli_comp_level -syn keyword ngxDirectiveThirdParty contained brotli_min_length -syn keyword ngxDirectiveThirdParty contained brotli_static -syn keyword ngxDirectiveThirdParty contained brotli_types -syn keyword ngxDirectiveThirdParty contained brotli_window - -" form-input-nginx-module -" https://github.com/calio/form-input-nginx-module -syn keyword ngxDirectiveThirdParty contained set_form_input -syn keyword ngxDirectiveThirdParty contained set_form_input_multi - -" character conversion nginx module using libiconv -" https://github.com/calio/iconv-nginx-module -syn keyword ngxDirectiveThirdParty contained iconv_buffer_size -syn keyword ngxDirectiveThirdParty contained iconv_filter -syn keyword ngxDirectiveThirdParty contained set_iconv - -" 3rd party modules list taken from -" https://www.nginx.com/resources/wiki/modules/ -" --------------------------------------------- - -" Nginx Module for Authenticating Akamai G2O requests -" https://github.com/kaltura/nginx_mod_akamai_g2o -syn keyword ngxDirectiveThirdParty contained g2o -syn keyword ngxDirectiveThirdParty contained g2o_data_header -syn keyword ngxDirectiveThirdParty contained g2o_hash_function -syn keyword ngxDirectiveThirdParty contained g2o_key -syn keyword ngxDirectiveThirdParty contained g2o_log_level -syn keyword ngxDirectiveThirdParty contained g2o_nonce -syn keyword ngxDirectiveThirdParty contained g2o_sign_header -syn keyword ngxDirectiveThirdParty contained g2o_time_window -syn keyword ngxDirectiveThirdParty contained g2o_version - -" nginx_lua_module -" https://github.com/alacner/nginx_lua_module -syn keyword ngxDirectiveThirdParty contained lua_file - -" Nginx Audio Track for HTTP Live Streaming -" https://github.com/flavioribeiro/nginx-audio-track-for-hls-module -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_output_format -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_output_header -syn keyword ngxDirectiveThirdParty contained ngx_hls_audio_track_rootpath - -" A Nginx module to dump backtrace when a worker process exits abnormally -" https://github.com/alibaba/nginx-backtrace -syn keyword ngxDirectiveThirdParty contained backtrace_log -syn keyword ngxDirectiveThirdParty contained backtrace_max_stack_size - -" circle_gif module -" https://github.com/evanmiller/nginx_circle_gif -syn keyword ngxDirectiveThirdParty contained circle_gif -syn keyword ngxDirectiveThirdParty contained circle_gif_max_radius -syn keyword ngxDirectiveThirdParty contained circle_gif_min_radius -syn keyword ngxDirectiveThirdParty contained circle_gif_step_radius - -" Upstream Consistent Hash -" https://github.com/replay/ngx_http_consistent_hash -syn keyword ngxDirectiveThirdParty contained consistent_hash - -" Nginx module for etags on dynamic content -" https://github.com/kali/nginx-dynamic-etags -syn keyword ngxDirectiveThirdParty contained dynamic_etags - -" Enhanced Nginx Memcached Module -" https://github.com/bpaquet/ngx_http_enhanced_memcached_module -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_allow_delete -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_allow_put -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_bind -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_buffer_size -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_connect_timeout -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_flush -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_flush_namespace -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_hash_keys_with_md5 -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_pass -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_read_timeout -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_send_timeout -syn keyword ngxDirectiveThirdParty contained enhanced_memcached_stats - -" nginx max connections queue -" https://github.com/ezmobius/nginx-ey-balancer -syn keyword ngxDirectiveThirdParty contained max_connections_max_queue_length -syn keyword ngxDirectiveThirdParty contained max_connections_queue_timeout - -" Nginx module for POST authentication and authorization -" https://github.com/veruu/ngx_form_auth -syn keyword ngxDirectiveThirdParty contained form_auth -syn keyword ngxDirectiveThirdParty contained form_auth_login -syn keyword ngxDirectiveThirdParty contained form_auth_pam_service -syn keyword ngxDirectiveThirdParty contained form_auth_password -syn keyword ngxDirectiveThirdParty contained form_auth_remote_user - -" ngx_http_accounting_module -" https://github.com/Lax/ngx_http_accounting_module -syn keyword ngxDirectiveThirdParty contained accounting -syn keyword ngxDirectiveThirdParty contained accounting_id -syn keyword ngxDirectiveThirdParty contained accounting_interval -syn keyword ngxDirectiveThirdParty contained accounting_log -syn keyword ngxDirectiveThirdParty contained accounting_perturb - -" concatenating files in a given context: CSS and JS files usually -" https://github.com/alibaba/nginx-http-concat -syn keyword ngxDirectiveThirdParty contained concat -syn keyword ngxDirectiveThirdParty contained concat_delimiter -syn keyword ngxDirectiveThirdParty contained concat_ignore_file_error -syn keyword ngxDirectiveThirdParty contained concat_max_files -syn keyword ngxDirectiveThirdParty contained concat_types -syn keyword ngxDirectiveThirdParty contained concat_unique - -" update upstreams' config by restful interface -" https://github.com/yzprofile/ngx_http_dyups_module -syn keyword ngxDirectiveThirdParty contained dyups_interface -syn keyword ngxDirectiveThirdParty contained dyups_shm_zone_size - -" add given content to the end of the response according to the condition specified -" https://github.com/flygoast/ngx_http_footer_if_filter -syn keyword ngxDirectiveThirdParty contained footer_if - -" NGINX HTTP Internal Redirect Module -" https://github.com/flygoast/ngx_http_internal_redirect -syn keyword ngxDirectiveThirdParty contained internal_redirect_if -syn keyword ngxDirectiveThirdParty contained internal_redirect_if_no_postpone - -" nginx-ip-blocker -" https://github.com/tmthrgd/nginx-ip-blocker -syn keyword ngxDirectiveThirdParty contained ip_blocker - -" IP2Location Nginx -" https://github.com/chrislim2888/ip2location-nginx -syn keyword ngxDirectiveThirdParty contained ip2location_database - -" Limit upload rate -" https://github.com/cfsego/limit_upload_rate -syn keyword ngxDirectiveThirdParty contained limit_upload_rate -syn keyword ngxDirectiveThirdParty contained limit_upload_rate_after -syn keyword ngxDirectiveThirdParty contained limit_upload_rate_log_level - -" limit the number of connections to upstream -" https://github.com/cfsego/nginx-limit-upstream -syn keyword ngxDirectiveThirdParty contained limit_upstream_conn -syn keyword ngxDirectiveThirdParty contained limit_upstream_log_level -syn keyword ngxDirectiveThirdParty contained limit_upstream_zone - -" conditional accesslog for nginx -" https://github.com/cfsego/ngx_log_if -syn keyword ngxDirectiveThirdParty contained access_log_bypass_if - -" log messages over ZeroMQ -" https://github.com/alticelabs/nginx-log-zmq -syn keyword ngxDirectiveThirdParty contained log_zmq_endpoint -syn keyword ngxDirectiveThirdParty contained log_zmq_format -syn keyword ngxDirectiveThirdParty contained log_zmq_off -syn keyword ngxDirectiveThirdParty contained log_zmq_server - -" simple module to uppercase/lowercase strings in the nginx config -" https://github.com/replay/ngx_http_lower_upper_case -syn keyword ngxDirectiveThirdParty contained lower -syn keyword ngxDirectiveThirdParty contained upper - -" content filter for nginx, which returns the md5 hash of the content otherwise returned -" https://github.com/kainswor/nginx_md5_filter -syn keyword ngxDirectiveThirdParty contained md5_filter - -" Non-blocking upstream module for Nginx to connect to MongoDB -" https://github.com/simpl/ngx_mongo -syn keyword ngxDirectiveThirdParty contained mongo_auth -syn keyword ngxDirectiveThirdParty contained mongo_bind -syn keyword ngxDirectiveThirdParty contained mongo_buffer_size -syn keyword ngxDirectiveThirdParty contained mongo_buffering -syn keyword ngxDirectiveThirdParty contained mongo_buffers -syn keyword ngxDirectiveThirdParty contained mongo_busy_buffers_size -syn keyword ngxDirectiveThirdParty contained mongo_connect_timeout -syn keyword ngxDirectiveThirdParty contained mongo_json -syn keyword ngxDirectiveThirdParty contained mongo_next_upstream -syn keyword ngxDirectiveThirdParty contained mongo_pass -syn keyword ngxDirectiveThirdParty contained mongo_query -syn keyword ngxDirectiveThirdParty contained mongo_read_timeout -syn keyword ngxDirectiveThirdParty contained mongo_send_timeout - -" Nginx OCSP processing module designed for response caching -" https://github.com/kyprizel/nginx_ocsp_proxy-module -syn keyword ngxDirectiveThirdParty contained ocsp_cache_timeout -syn keyword ngxDirectiveThirdParty contained ocsp_proxy - -" Nginx OpenSSL version check at startup -" https://github.com/apcera/nginx-openssl-version -syn keyword ngxDirectiveThirdParty contained openssl_builddate_minimum -syn keyword ngxDirectiveThirdParty contained openssl_version_minimum - -" Automatic PageSpeed optimization module for Nginx -" https://github.com/pagespeed/ngx_pagespeed -syn keyword ngxDirectiveThirdParty contained pagespeed - -" PECL Memcache standard hashing compatible loadbalancer for Nginx -" https://github.com/replay/ngx_http_php_memcache_standard_balancer -syn keyword ngxDirectiveThirdParty contained hash_key - -" nginx module to parse php sessions -" https://github.com/replay/ngx_http_php_session -syn keyword ngxDirectiveThirdParty contained php_session_parse -syn keyword ngxDirectiveThirdParty contained php_session_strip_formatting - -" Nginx HTTP rDNS module -" https://github.com/flant/nginx-http-rdns -syn keyword ngxDirectiveThirdParty contained rdns -syn keyword ngxDirectiveThirdParty contained rdns_allow -syn keyword ngxDirectiveThirdParty contained rdns_deny - -" Streaming regular expression replacement in response bodies -" https://github.com/openresty/replace-filter-nginx-module -syn keyword ngxDirectiveThirdParty contained replace_filter -syn keyword ngxDirectiveThirdParty contained replace_filter_last_modified -syn keyword ngxDirectiveThirdParty contained replace_filter_max_buffered_size -syn keyword ngxDirectiveThirdParty contained replace_filter_skip -syn keyword ngxDirectiveThirdParty contained replace_filter_types - -" Link RRDtool's graphing facilities directly into nginx -" https://github.com/evanmiller/mod_rrd_graph -syn keyword ngxDirectiveThirdParty contained rrd_graph -syn keyword ngxDirectiveThirdParty contained rrd_graph_root - -" Module for nginx to proxy rtmp using http protocol -" https://github.com/kwojtek/nginx-rtmpt-proxy-module -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_http_timeout -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_rtmp_timeout -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_stat -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_stylesheet -syn keyword ngxDirectiveThirdParty contained rtmpt_proxy_target - -" Syntactically Awesome NGINX Module -" https://github.com/mneudert/sass-nginx-module -syn keyword ngxDirectiveThirdParty contained sass_compile -syn keyword ngxDirectiveThirdParty contained sass_error_log -syn keyword ngxDirectiveThirdParty contained sass_include_path -syn keyword ngxDirectiveThirdParty contained sass_indent -syn keyword ngxDirectiveThirdParty contained sass_is_indented_syntax -syn keyword ngxDirectiveThirdParty contained sass_linefeed -syn keyword ngxDirectiveThirdParty contained sass_output_style -syn keyword ngxDirectiveThirdParty contained sass_precision -syn keyword ngxDirectiveThirdParty contained sass_source_comments -syn keyword ngxDirectiveThirdParty contained sass_source_map_embed - -" Nginx Selective Cache Purge Module -" https://github.com/wandenberg/nginx-selective-cache-purge-module -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_query -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_database -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_host -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_password -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_port -syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_unix_socket - -" cconv nginx module -" https://github.com/liseen/set-cconv-nginx-module -syn keyword ngxDirectiveThirdParty contained set_cconv_to_simp -syn keyword ngxDirectiveThirdParty contained set_cconv_to_trad -syn keyword ngxDirectiveThirdParty contained set_pinyin_to_normal - -" Nginx module that allows the setting of variables to the value of a variety of hashes -" https://github.com/simpl/ngx_http_set_hash -syn keyword ngxDirectiveThirdParty contained set_md5 -syn keyword ngxDirectiveThirdParty contained set_md5_upper -syn keyword ngxDirectiveThirdParty contained set_murmur2 -syn keyword ngxDirectiveThirdParty contained set_murmur2_upper -syn keyword ngxDirectiveThirdParty contained set_sha1 -syn keyword ngxDirectiveThirdParty contained set_sha1_upper - -" Nginx module to set the language of a request based on a number of options -" https://github.com/simpl/ngx_http_set_lang -syn keyword ngxDirectiveThirdParty contained lang_cookie -syn keyword ngxDirectiveThirdParty contained lang_get_var -syn keyword ngxDirectiveThirdParty contained lang_host -syn keyword ngxDirectiveThirdParty contained lang_list -syn keyword ngxDirectiveThirdParty contained lang_post_var -syn keyword ngxDirectiveThirdParty contained lang_referer -syn keyword ngxDirectiveThirdParty contained set_lang -syn keyword ngxDirectiveThirdParty contained set_lang_method - -" Nginx Sorted Querystring Module -" https://github.com/wandenberg/nginx-sorted-querystring-module -syn keyword ngxDirectiveThirdParty contained sorted_querysting_filter_parameter - -" Nginx upstream module for Sphinx 2.x search daemon -" https://github.com/reeteshranjan/sphinx2-nginx-module -syn keyword ngxDirectiveThirdParty contained sphinx2_bind -syn keyword ngxDirectiveThirdParty contained sphinx2_buffer_size -syn keyword ngxDirectiveThirdParty contained sphinx2_connect_timeout -syn keyword ngxDirectiveThirdParty contained sphinx2_next_upstream -syn keyword ngxDirectiveThirdParty contained sphinx2_pass -syn keyword ngxDirectiveThirdParty contained sphinx2_read_timeout -syn keyword ngxDirectiveThirdParty contained sphinx2_send_timeout - -" Nginx module for retrieving user attributes and groups from SSSD -" https://github.com/veruu/ngx_sssd_info -syn keyword ngxDirectiveThirdParty contained sssd_info -syn keyword ngxDirectiveThirdParty contained sssd_info_attribute -syn keyword ngxDirectiveThirdParty contained sssd_info_attribute_separator -syn keyword ngxDirectiveThirdParty contained sssd_info_attributes -syn keyword ngxDirectiveThirdParty contained sssd_info_group -syn keyword ngxDirectiveThirdParty contained sssd_info_group_separator -syn keyword ngxDirectiveThirdParty contained sssd_info_groups -syn keyword ngxDirectiveThirdParty contained sssd_info_output_to - -" An nginx module for sending statistics to statsd -" https://github.com/zebrafishlabs/nginx-statsd -syn keyword ngxDirectiveThirdParty contained statsd_count -syn keyword ngxDirectiveThirdParty contained statsd_sample_rate -syn keyword ngxDirectiveThirdParty contained statsd_server -syn keyword ngxDirectiveThirdParty contained statsd_timing - -" ngx_stream_echo - TCP/stream echo module for NGINX (a port of the ngx_http_echo module) -" https://github.com/openresty/stream-echo-nginx-module -syn keyword ngxDirectiveThirdParty contained echo -syn keyword ngxDirectiveThirdParty contained echo_client_error_log_level -syn keyword ngxDirectiveThirdParty contained echo_discard_request -syn keyword ngxDirectiveThirdParty contained echo_duplicate -syn keyword ngxDirectiveThirdParty contained echo_flush_wait -syn keyword ngxDirectiveThirdParty contained echo_lingering_close -syn keyword ngxDirectiveThirdParty contained echo_lingering_time -syn keyword ngxDirectiveThirdParty contained echo_lingering_timeout -syn keyword ngxDirectiveThirdParty contained echo_read_buffer_size -syn keyword ngxDirectiveThirdParty contained echo_read_bytes -syn keyword ngxDirectiveThirdParty contained echo_read_line -syn keyword ngxDirectiveThirdParty contained echo_read_timeout -syn keyword ngxDirectiveThirdParty contained echo_request_data -syn keyword ngxDirectiveThirdParty contained echo_send_timeout -syn keyword ngxDirectiveThirdParty contained echo_sleep - -" Embed the power of Lua into NGINX TCP/UDP servers -" https://github.com/openresty/stream-lua-nginx-module -syn keyword ngxDirectiveThirdParty contained lua_add_variable -syn keyword ngxDirectiveThirdParty contained preread_by_lua_block -syn keyword ngxDirectiveThirdParty contained preread_by_lua_file -syn keyword ngxDirectiveThirdParty contained preread_by_lua_no_postpone - -" nginx-upsync-module -" https://github.com/weibocom/nginx-upsync-module -syn keyword ngxDirectiveThirdParty contained upstream_show -syn keyword ngxDirectiveThirdParty contained upsync -syn keyword ngxDirectiveThirdParty contained upsync_dump_path -syn keyword ngxDirectiveThirdParty contained upsync_lb - -" Whitespace stripper for nginx -" https://github.com/evanmiller/mod_strip -syn keyword ngxDirectiveThirdParty contained strip - -" Split one big HTTP/Range request to multiple subrange requesets -" https://github.com/Qihoo360/ngx_http_subrange_module -syn keyword ngxDirectiveThirdParty contained subrange - -" summarizer-nginx-module -" https://github.com/reeteshranjan/summarizer-nginx-module -syn keyword ngxDirectiveThirdParty contained summarizer_bind -syn keyword ngxDirectiveThirdParty contained summarizer_buffer_size -syn keyword ngxDirectiveThirdParty contained summarizer_connect_timeout -syn keyword ngxDirectiveThirdParty contained summarizer_next_upstream -syn keyword ngxDirectiveThirdParty contained summarizer_pass -syn keyword ngxDirectiveThirdParty contained summarizer_read_timeout -syn keyword ngxDirectiveThirdParty contained summarizer_send_timeout - -" nginx module providing API to communicate with supervisord and manage (start/stop) backends on-demand -" https://github.com/FRiCKLE/ngx_supervisord -syn keyword ngxDirectiveThirdParty contained supervisord -syn keyword ngxDirectiveThirdParty contained supervisord_inherit_backend_status -syn keyword ngxDirectiveThirdParty contained supervisord_name -syn keyword ngxDirectiveThirdParty contained supervisord_start -syn keyword ngxDirectiveThirdParty contained supervisord_stop - -" simple robot mitigation module using cookie based challenge/response technique. Not supported any more. -" https://github.com/kyprizel/testcookie-nginx-module -syn keyword ngxDirectiveThirdParty contained testcookie -syn keyword ngxDirectiveThirdParty contained testcookie_arg -syn keyword ngxDirectiveThirdParty contained testcookie_deny_keepalive -syn keyword ngxDirectiveThirdParty contained testcookie_domain -syn keyword ngxDirectiveThirdParty contained testcookie_expires -syn keyword ngxDirectiveThirdParty contained testcookie_fallback -syn keyword ngxDirectiveThirdParty contained testcookie_get_only -syn keyword ngxDirectiveThirdParty contained testcookie_httponly_flag -syn keyword ngxDirectiveThirdParty contained testcookie_https_location -syn keyword ngxDirectiveThirdParty contained testcookie_internal -syn keyword ngxDirectiveThirdParty contained testcookie_max_attempts -syn keyword ngxDirectiveThirdParty contained testcookie_name -syn keyword ngxDirectiveThirdParty contained testcookie_p3p -syn keyword ngxDirectiveThirdParty contained testcookie_pass -syn keyword ngxDirectiveThirdParty contained testcookie_path -syn keyword ngxDirectiveThirdParty contained testcookie_port_in_redirect -syn keyword ngxDirectiveThirdParty contained testcookie_redirect_via_refresh -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie_iv -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_encrypt_cookie_key -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_status -syn keyword ngxDirectiveThirdParty contained testcookie_refresh_template -syn keyword ngxDirectiveThirdParty contained testcookie_samesite -syn keyword ngxDirectiveThirdParty contained testcookie_secret -syn keyword ngxDirectiveThirdParty contained testcookie_secure_flag -syn keyword ngxDirectiveThirdParty contained testcookie_session -syn keyword ngxDirectiveThirdParty contained testcookie_whitelist - -" ngx_http_types_filter_module -" https://github.com/flygoast/ngx_http_types_filter -syn keyword ngxDirectiveThirdParty contained types_filter -syn keyword ngxDirectiveThirdParty contained types_filter_use_default - -" A module allowing the nginx to use files embedded in a zip file -" https://github.com/youzee/nginx-unzip-module -syn keyword ngxDirectiveThirdParty contained file_in_unzip -syn keyword ngxDirectiveThirdParty contained file_in_unzip_archivefile -syn keyword ngxDirectiveThirdParty contained file_in_unzip_extract - -" An asynchronous domain name resolve module for nginx upstream -" https://github.com/wdaike/ngx_upstream_jdomain -syn keyword ngxDirectiveThirdParty contained jdomain - -" Nginx url encoding converting module -" https://github.com/vozlt/nginx-module-url -syn keyword ngxDirectiveThirdParty contained url_encoding_convert -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_alloc_size -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_alloc_size_x -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_from -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_phase -syn keyword ngxDirectiveThirdParty contained url_encoding_convert_to - -" A nginx module to match browsers and crawlers -" https://github.com/alibaba/nginx-http-user-agent -syn keyword ngxDirectiveThirdParty contained user_agent - -" nginx load-balancer module implementing ketama consistent hashing -" https://github.com/flygoast/ngx_http_upstream_ketama_chash -syn keyword ngxDirectiveThirdParty contained ketama_chash - -" nginx-sticky-module-ng -" https://github.com/ayty-adrianomartins/nginx-sticky-module-ng -syn keyword ngxDirectiveThirdParty contained sticky_no_fallback - -" dynamic linking and call the function of your application -" https://github.com/Taymindis/nginx-link-function -syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_prop -syn keyword ngxDirectiveThirdParty contained ngx_link_func_add_req_header -syn keyword ngxDirectiveThirdParty contained ngx_link_func_ca_cert -syn keyword ngxDirectiveThirdParty contained ngx_link_func_call -syn keyword ngxDirectiveThirdParty contained ngx_link_func_download_link_lib -syn keyword ngxDirectiveThirdParty contained ngx_link_func_lib -syn keyword ngxDirectiveThirdParty contained ngx_link_func_shm_size -syn keyword ngxDirectiveThirdParty contained ngx_link_func_subrequest - -" purge content from FastCGI, proxy, SCGI and uWSGI caches -" https://github.com/torden/ngx_cache_purge -syn keyword ngxDirectiveThirdParty contained cache_purge_response_type - -" set the flags "HttpOnly", "secure" and "SameSite" for cookies -" https://github.com/AirisX/nginx_cookie_flag_module -syn keyword ngxDirectiveThirdParty contained set_cookie_flag - -" Embed websockify into Nginx (convert any tcp connection into websocket) " https://github.com/tg123/websockify-nginx-module syn keyword ngxDirectiveThirdParty contained websockify_buffer_size syn keyword ngxDirectiveThirdParty contained websockify_connect_timeout @@ -2415,55 +1980,6 @@ syn keyword ngxDirectiveThirdParty contained websockify_pass syn keyword ngxDirectiveThirdParty contained websockify_read_timeout syn keyword ngxDirectiveThirdParty contained websockify_send_timeout -" IP2Location Nginx -" https://github.com/ip2location/ip2location-nginx -syn keyword ngxDirectiveThirdParty contained ip2location_addresstype -syn keyword ngxDirectiveThirdParty contained ip2location_areacode -syn keyword ngxDirectiveThirdParty contained ip2location_category -syn keyword ngxDirectiveThirdParty contained ip2location_city -syn keyword ngxDirectiveThirdParty contained ip2location_country_long -syn keyword ngxDirectiveThirdParty contained ip2location_country_short -syn keyword ngxDirectiveThirdParty contained ip2location_domain -syn keyword ngxDirectiveThirdParty contained ip2location_elevation -syn keyword ngxDirectiveThirdParty contained ip2location_iddcode -syn keyword ngxDirectiveThirdParty contained ip2location_isp -syn keyword ngxDirectiveThirdParty contained ip2location_latitude -syn keyword ngxDirectiveThirdParty contained ip2location_longitude -syn keyword ngxDirectiveThirdParty contained ip2location_mcc -syn keyword ngxDirectiveThirdParty contained ip2location_mnc -syn keyword ngxDirectiveThirdParty contained ip2location_mobilebrand -syn keyword ngxDirectiveThirdParty contained ip2location_netspeed -syn keyword ngxDirectiveThirdParty contained ip2location_proxy -syn keyword ngxDirectiveThirdParty contained ip2location_proxy_recursive -syn keyword ngxDirectiveThirdParty contained ip2location_region -syn keyword ngxDirectiveThirdParty contained ip2location_timezone -syn keyword ngxDirectiveThirdParty contained ip2location_usagetype -syn keyword ngxDirectiveThirdParty contained ip2location_weatherstationcode -syn keyword ngxDirectiveThirdParty contained ip2location_weatherstationname -syn keyword ngxDirectiveThirdParty contained ip2location_zipcode - -" IP2Proxy module for Nginx -" https://github.com/ip2location/ip2proxy-nginx -syn keyword ngxDirectiveThirdParty contained ip2proxy_as -syn keyword ngxDirectiveThirdParty contained ip2proxy_asn -syn keyword ngxDirectiveThirdParty contained ip2proxy_city -syn keyword ngxDirectiveThirdParty contained ip2proxy_country_long -syn keyword ngxDirectiveThirdParty contained ip2proxy_country_short -syn keyword ngxDirectiveThirdParty contained ip2proxy_database -syn keyword ngxDirectiveThirdParty contained ip2proxy_domain -syn keyword ngxDirectiveThirdParty contained ip2proxy_isp -syn keyword ngxDirectiveThirdParty contained ip2proxy_is_proxy -syn keyword ngxDirectiveThirdParty contained ip2proxy_last_seen -syn keyword ngxDirectiveThirdParty contained ip2proxy_provider -syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy -syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_recursive -syn keyword ngxDirectiveThirdParty contained ip2proxy_proxy_type -syn keyword ngxDirectiveThirdParty contained ip2proxy_region -syn keyword ngxDirectiveThirdParty contained ip2proxy_threat -syn keyword ngxDirectiveThirdParty contained ip2proxy_usage_type - - - " highlight hi def link ngxComment Comment diff --git a/module/lib/json.hpp b/module/lib/json.hpp index 87475ab3..cb27e058 100644 --- a/module/lib/json.hpp +++ b/module/lib/json.hpp @@ -1,12 +1,12 @@ /* __ _____ _____ _____ __| | __| | | | JSON for Modern C++ -| | |__ | | | | | | version 3.10.4 +| | |__ | | | | | | version 3.10.5 |_____|_____|_____|_|___| https://github.com/nlohmann/json Licensed under the MIT License . SPDX-License-Identifier: MIT -Copyright (c) 2013-2019 Niels Lohmann . +Copyright (c) 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 @@ -27,12 +27,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/****************************************************************************\ + * Note on documentation: The source files contain links to the online * + * documentation of the public API at https://json.nlohmann.me. This URL * + * contains the most recent documentation and should also be applicable to * + * previous versions; documentation for deprecated functions is not * + * removed, but marked deprecated. See "Generate documentation" section in * + * file doc/README.md. * +\****************************************************************************/ + #ifndef INCLUDE_NLOHMANN_JSON_HPP_ #define INCLUDE_NLOHMANN_JSON_HPP_ #define NLOHMANN_JSON_VERSION_MAJOR 3 #define NLOHMANN_JSON_VERSION_MINOR 10 -#define NLOHMANN_JSON_VERSION_PATCH 4 +#define NLOHMANN_JSON_VERSION_PATCH 5 #include // all_of, find, for_each #include // nullptr_t, ptrdiff_t, size_t @@ -2325,6 +2334,66 @@ using is_detected_convertible = #define JSON_HAS_CPP_11 #endif +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1940 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + // disable documentation warnings on clang #if defined(__clang__) #pragma clang diagnostic push @@ -2332,7 +2401,7 @@ using is_detected_convertible = #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" #endif -// allow to disable exceptions +// allow disabling exceptions #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) #define JSON_THROW(exception) throw exception #define JSON_TRY try @@ -2366,7 +2435,7 @@ using is_detected_convertible = #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER #endif -// allow to override assert +// allow overriding assert #if !defined(JSON_ASSERT) #include // assert #define JSON_ASSERT(x) assert(x) @@ -2734,34 +2803,8 @@ namespace detail // exceptions // //////////////// -/*! -@brief general exception of the @ref basic_json class - -This class is an extension of `std::exception` objects with a member @a id for -exception ids. It is used as the base class for all exceptions thrown by the -@ref basic_json class. This class can hence be used as "wildcard" to catch -exceptions. - -Subclasses: -- @ref parse_error for exceptions indicating a parse error -- @ref invalid_iterator for exceptions indicating errors with iterators -- @ref type_error for exceptions indicating executing a member function with - a wrong type -- @ref out_of_range for exceptions indicating access out of the defined range -- @ref other_error for exceptions indicating other library errors - -@internal -@note 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. -@endinternal - -@liveexample{The following code shows how arbitrary library exceptions can be -caught.,exception} - -@since version 3.0.0 -*/ +/// @brief general exception of the @ref basic_json class +/// @sa https://json.nlohmann.me/api/basic_json/exception/ class exception : public std::exception { public: @@ -2776,7 +2819,7 @@ class exception : public std::exception protected: JSON_HEDLEY_NON_NULL(3) - exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} + exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing) static std::string name(const std::string& ename, int id_) { @@ -2852,51 +2895,8 @@ class exception : public std::exception std::runtime_error m; }; -/*! -@brief exception indicating a parse error - -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. - -Member @a byte holds the byte index of the last read character in the input -file. - -Exceptions have ids 1xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | 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 @a byte indicates the error position. -json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above 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. -json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid. -json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects. -json.exception.parse_error.105 | parse error: operation must have string member 'op' | 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. -json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`. -json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character. -json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences. -json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number. -json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read. -json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read. -json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read. -json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet). -json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed. - -@note 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). - -@liveexample{The following code shows how a `parse_error` exception can be -caught.,parse_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ +/// @brief exception indicating a parse error +/// @sa https://json.nlohmann.me/api/basic_json/parse_error/ class parse_error : public exception { public: @@ -2914,7 +2914,7 @@ class parse_error : public exception { std::string w = exception::name("parse_error", id_) + "parse error" + position_string(pos) + ": " + exception::diagnostics(context) + what_arg; - return parse_error(id_, pos.chars_read_total, w.c_str()); + return {id_, pos.chars_read_total, w.c_str()}; } template @@ -2923,7 +2923,7 @@ class parse_error : public exception std::string w = exception::name("parse_error", id_) + "parse error" + (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") + ": " + exception::diagnostics(context) + what_arg; - return parse_error(id_, byte_, w.c_str()); + return {id_, byte_, w.c_str()}; } /*! @@ -2948,43 +2948,8 @@ class parse_error : public exception } }; -/*! -@brief exception indicating errors with iterators - -This exception is thrown if iterators passed to a library function do not match -the expected semantics. - -Exceptions have ids 2xx. - -name / id | example message | description ------------------------------------ | --------------- | ------------------------- -json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a 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. -json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref 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. -json.exception.invalid_iterator.204 | iterators out of range | 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 (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid. -json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid. -json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range. -json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | 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. -json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered. -json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid. -json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to. -json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container. -json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered. -json.exception.invalid_iterator.214 | cannot get value | 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 @ref begin(). - -@liveexample{The following code shows how an `invalid_iterator` exception can be -caught.,invalid_iterator} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ +/// @brief exception indicating errors with iterators +/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/ class invalid_iterator : public exception { public: @@ -2992,7 +2957,7 @@ class invalid_iterator : public exception static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context) { std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg; - return invalid_iterator(id_, w.c_str()); + return {id_, w.c_str()}; } private: @@ -3001,45 +2966,8 @@ class invalid_iterator : public exception : exception(id_, what_arg) {} }; -/*! -@brief exception indicating executing a member function with a wrong type - -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. - -name / id | example message | description ------------------------------ | --------------- | ------------------------- -json.exception.type_error.301 | cannot create object from initializer list | 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. -json.exception.type_error.302 | type must be object, but is array | 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. -json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. -json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. -json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. -json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. -json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types. -json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types. -json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types. -json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types. -json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types. -json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types. -json.exception.type_error.313 | invalid value to unflatten | The @ref 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. -json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers. -json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive. -json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref 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. | -json.exception.type_error.317 | JSON value cannot be serialized to requested format | 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) | - -@liveexample{The following code shows how a `type_error` exception can be -caught.,type_error} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref out_of_range for exceptions indicating access out of the defined range -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ +/// @brief exception indicating executing a member function with a wrong type +/// @sa https://json.nlohmann.me/api/basic_json/type_error/ class type_error : public exception { public: @@ -3047,7 +2975,7 @@ class type_error : public exception static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context) { std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg; - return type_error(id_, w.c_str()); + return {id_, w.c_str()}; } private: @@ -3055,39 +2983,8 @@ class type_error : public exception type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} }; -/*! -@brief exception indicating access out of the defined 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. - -name / id | example message | description -------------------------------- | --------------- | ------------------------- -json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1. -json.exception.out_of_range.402 | array index '-' (3) is out of range | 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. -json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object. -json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved. -json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value. -json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF. -json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) | -json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. | -json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string | - -@liveexample{The following code shows how an `out_of_range` exception can be -caught.,out_of_range} - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref other_error for exceptions indicating other library errors - -@since version 3.0.0 -*/ +/// @brief exception indicating access out of the defined range +/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/ class out_of_range : public exception { public: @@ -3095,7 +2992,7 @@ class out_of_range : public exception static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context) { std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg; - return out_of_range(id_, w.c_str()); + return {id_, w.c_str()}; } private: @@ -3103,30 +3000,8 @@ class out_of_range : public exception out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} }; -/*! -@brief exception indicating other library errors - -This exception is thrown in case of errors that cannot be classified with the -other exception types. - -Exceptions have ids 5xx. - -name / id | example message | description ------------------------------- | --------------- | ------------------------- -json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed. - -@sa - @ref exception for the base class of the library exceptions -@sa - @ref parse_error for exceptions indicating a parse error -@sa - @ref invalid_iterator for exceptions indicating errors with iterators -@sa - @ref type_error for exceptions indicating executing a member function with - a wrong type -@sa - @ref out_of_range for exceptions indicating access out of the defined range - -@liveexample{The following code shows how an `other_error` exception can be -caught.,other_error} - -@since version 3.0.0 -*/ +/// @brief exception indicating other library errors +/// @sa https://json.nlohmann.me/api/basic_json/other_error/ class other_error : public exception { public: @@ -3134,13 +3009,14 @@ class other_error : public exception static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context) { std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg; - return other_error(id_, w.c_str()); + return {id_, w.c_str()}; } private: JSON_HEDLEY_NON_NULL(3) other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} }; + } // namespace detail } // namespace nlohmann @@ -3298,7 +3174,7 @@ struct static_const }; template -constexpr T static_const::value; +constexpr T static_const::value; // NOLINT(readability-redundant-declaration) } // namespace detail } // namespace nlohmann @@ -3434,6 +3310,8 @@ for serialization. template struct adl_serializer; +/// a class to store JSON values +/// @sa https://json.nlohmann.me/api/basic_json/ template class ObjectType = std::map, template class ArrayType = std::vector, @@ -3447,40 +3325,24 @@ template class ObjectType = class BinaryType = std::vector> class basic_json; -/*! -@brief 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. - -@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) - -@since version 2.0.0 -*/ +/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document +/// @sa https://json.nlohmann.me/api/json_pointer/ template class json_pointer; /*! -@brief default JSON class - -This type is the default specialization of the @ref basic_json class which -uses the standard template types. - -@since version 1.0.0 +@brief default specialization +@sa https://json.nlohmann.me/api/json/ */ using json = basic_json<>; +/// @brief a minimal map-like container that preserves insertion order +/// @sa https://json.nlohmann.me/api/ordered_map/ template struct ordered_map; -/*! -@brief ordered JSON class - -This type preserves the insertion order of object keys. - -@since version 3.9.0 -*/ +/// @brief specialization that maintains the insertion order of object keys +/// @sa https://json.nlohmann.me/api/ordered_json/ using ordered_json = basic_json; } // namespace nlohmann @@ -3950,8 +3812,18 @@ T conditional_static_cast(U value) // #include -#ifdef JSON_HAS_CPP_17 - #include +#if JSON_HAS_EXPERIMENTAL_FILESYSTEM +#include +namespace nlohmann::detail +{ +namespace std_fs = std::experimental::filesystem; +} // namespace nlohmann::detail +#elif JSON_HAS_FILESYSTEM +#include +namespace nlohmann::detail +{ +namespace std_fs = std::filesystem; +} // namespace nlohmann::detail #endif namespace nlohmann @@ -4379,9 +4251,9 @@ void from_json(const BasicJsonType& j, std::unordered_map -void from_json(const BasicJsonType& j, std::filesystem::path& p) +void from_json(const BasicJsonType& j, std_fs::path& p) { if (JSON_HEDLEY_UNLIKELY(!j.is_string())) { @@ -4626,8 +4498,18 @@ class tuple_element> // #include -#ifdef JSON_HAS_CPP_17 - #include +#if JSON_HAS_EXPERIMENTAL_FILESYSTEM +#include +namespace nlohmann::detail +{ +namespace std_fs = std::experimental::filesystem; +} // namespace nlohmann::detail +#elif JSON_HAS_FILESYSTEM +#include +namespace nlohmann::detail +{ +namespace std_fs = std::filesystem; +} // namespace nlohmann::detail #endif namespace nlohmann @@ -5002,9 +4884,9 @@ void to_json(BasicJsonType& j, const T& t) to_json_tuple_impl(j, t, make_index_sequence::value> {}); } -#ifdef JSON_HAS_CPP_17 +#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM template -void to_json(BasicJsonType& j, const std::filesystem::path& p) +void to_json(BasicJsonType& j, const std_fs::path& p) { j = p.string(); } @@ -5038,20 +4920,12 @@ constexpr const auto& to_json = detail::static_const::value; namespace nlohmann { +/// @sa https://json.nlohmann.me/api/adl_serializer/ template struct adl_serializer { - /*! - @brief convert a JSON value to any value type - - This function is usually called by the `get()` function of the - @ref basic_json class (either explicit or via conversion operators). - - @note This function is chosen for default-constructible value types. - - @param[in] j JSON value to read from - @param[in,out] val value to write to - */ + /// @brief convert a JSON value to any value type + /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ template static auto from_json(BasicJsonType && j, TargetType& val) noexcept( noexcept(::nlohmann::from_json(std::forward(j), val))) @@ -5060,18 +4934,8 @@ struct adl_serializer ::nlohmann::from_json(std::forward(j), val); } - /*! - @brief convert a JSON value to any value type - - This function is usually called by the `get()` function of the - @ref basic_json class (either explicit or via conversion operators). - - @note This function is chosen for value types which are not default-constructible. - - @param[in] j JSON value to read from - - @return copy of the JSON value, converted to @a ValueType - */ + /// @brief convert a JSON value to any value type + /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ template static auto from_json(BasicJsonType && j) noexcept( noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) @@ -5080,15 +4944,8 @@ struct adl_serializer return ::nlohmann::from_json(std::forward(j), detail::identity_tag {}); } - /*! - @brief convert any value type to a JSON value - - This function is usually called by the constructors of the @ref basic_json - class. - - @param[in,out] j JSON value to write to - @param[in] val value to read from - */ + /// @brief convert any value type to a JSON value + /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/ template static auto to_json(BasicJsonType& j, TargetType && val) noexcept( noexcept(::nlohmann::to_json(j, std::forward(val)))) @@ -5109,46 +4966,38 @@ struct adl_serializer namespace nlohmann { -/*! -@brief an internal type for a backed binary type - -This type extends the template parameter @a 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. - -@tparam BinaryType container to store bytes (`std::vector` by - default) - -@since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0. -*/ +/// @brief an internal type for a backed binary type +/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/ template class byte_container_with_subtype : public BinaryType { public: - /// the type of the underlying container using container_type = BinaryType; - /// the type of the subtype using subtype_type = std::uint64_t; + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ byte_container_with_subtype() noexcept(noexcept(container_type())) : container_type() {} + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) : container_type(b) {} + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) : container_type(std::move(b)) {} + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) : container_type(b) , m_subtype(subtype_) , m_has_subtype(true) {} + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) : container_type(std::move(b)) , m_subtype(subtype_) @@ -5166,97 +5015,30 @@ class byte_container_with_subtype : public BinaryType return !(rhs == *this); } - /*! - @brief sets the binary subtype - - Sets the binary subtype of the value, also flags a binary JSON value as - having a subtype, which has implications for serialization. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ + /// @brief sets the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ void set_subtype(subtype_type subtype_) noexcept { m_subtype = subtype_; m_has_subtype = true; } - /*! - @brief return the binary subtype - - 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 the numerical subtype of the binary value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0; fixed return value to properly return - subtype_type(-1) as documented in version 3.10.0 - */ + /// @brief return the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ constexpr subtype_type subtype() const noexcept { - return m_has_subtype ? m_subtype : subtype_type(-1); + return m_has_subtype ? m_subtype : static_cast(-1); } - /*! - @brief return whether the value has a subtype - - @return whether the value has a subtype - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref clear_subtype() -- clears the binary subtype - - @since version 3.8.0 - */ + /// @brief return whether the value has a subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ constexpr bool has_subtype() const noexcept { return m_has_subtype; } - /*! - @brief clears the binary subtype - - 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. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @sa see @ref subtype() -- return the binary subtype - @sa see @ref set_subtype() -- sets the binary subtype - @sa see @ref has_subtype() -- returns whether or not the binary value has a - subtype - - @since version 3.8.0 - */ + /// @brief clears the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ void clear_subtype() noexcept { m_subtype = 0; @@ -5529,7 +5311,7 @@ class input_stream_adapter // std::istream/std::streambuf use std::char_traits::to_int_type, to // ensure that std::char_traits::eof() and the character 0xFF do not - // end up as the same value, eg. 0xFFFFFFFF. + // end up as the same value, e.g. 0xFFFFFFFF. std::char_traits::int_type get_character() { auto res = sb->sbumpc(); @@ -5875,7 +5657,7 @@ auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) / } // This class only handles inputs of input_buffer_adapter type. -// It's required so that expressions like {ptr, len} can be implicitely casted +// It's required so that expressions like {ptr, len} can be implicitly cast // to the correct adapter. class span_input_adapter { @@ -5968,7 +5750,7 @@ struct json_sax virtual bool number_unsigned(number_unsigned_t val) = 0; /*! - @brief an floating-point number was read + @brief a floating-point number was read @param[in] val floating-point value @param[in] s raw token value @return whether parsing should proceed @@ -5976,18 +5758,18 @@ struct json_sax virtual bool number_float(number_float_t val, const string_t& s) = 0; /*! - @brief a string was read + @brief a string value was read @param[in] val string value @return whether parsing should proceed - @note It is safe to move the passed string. + @note It is safe to move the passed string value. */ virtual bool string(string_t& val) = 0; /*! - @brief a binary string was read + @brief a binary value was read @param[in] val binary value @return whether parsing should proceed - @note It is safe to move the passed binary. + @note It is safe to move the passed binary value. */ virtual bool binary(binary_t& val) = 0; @@ -6134,7 +5916,7 @@ class json_sax_dom_parser { ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) + if (JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back())); } @@ -6160,7 +5942,7 @@ class json_sax_dom_parser { ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); - if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) + if (JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back())); } @@ -6315,7 +6097,7 @@ class json_sax_dom_callback_parser ref_stack.push_back(val.second); // check object limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back())); } @@ -6385,7 +6167,7 @@ class json_sax_dom_callback_parser ref_stack.push_back(val.second); // check array limit - if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size())) + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) { JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back())); } @@ -6588,7 +6370,7 @@ class json_sax_acceptor return true; } - bool start_object(std::size_t /*unused*/ = std::size_t(-1)) + bool start_object(std::size_t /*unused*/ = static_cast(-1)) { return true; } @@ -6603,7 +6385,7 @@ class json_sax_acceptor return true; } - bool start_array(std::size_t /*unused*/ = std::size_t(-1)) + bool start_array(std::size_t /*unused*/ = static_cast(-1)) { return true; } @@ -6971,7 +6753,7 @@ class lexer : public lexer_base // low surrogate occupies the least significant 15 bits + static_cast(codepoint2) // there is still the 0xD800, 0xDC00 and 0x10000 noise - // in the result so we have to subtract with: + // in the result, so we have to subtract with: // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 - 0x35FDC00u); } @@ -8075,7 +7857,7 @@ class lexer : public lexer_base { // escape control characters std::array cs{{}}; - (std::snprintf)(cs.data(), cs.size(), "", static_cast(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + static_cast((std::snprintf)(cs.data(), cs.size(), "", static_cast(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) result += cs.data(); } else @@ -8169,17 +7951,17 @@ class lexer : public lexer_base // literals case 't': { - std::array true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}}; + std::array true_literal = {{static_cast('t'), static_cast('r'), static_cast('u'), static_cast('e')}}; return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); } case 'f': { - std::array false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}}; + std::array false_literal = {{static_cast('f'), static_cast('a'), static_cast('l'), static_cast('s'), static_cast('e')}}; return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); } case 'n': { - std::array null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}}; + std::array null_literal = {{static_cast('n'), static_cast('u'), static_cast('l'), static_cast('l')}}; return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); } @@ -8430,7 +8212,7 @@ enum class cbor_tag_handler_t @note from https://stackoverflow.com/a/1001328/266378 */ -static inline bool little_endianess(int num = 1) noexcept +static inline bool little_endianness(int num = 1) noexcept { return *reinterpret_cast(&num) == 1; } @@ -8549,7 +8331,7 @@ class binary_reader std::int32_t document_size{}; get_number(input_format_t::bson, document_size); - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) { return false; } @@ -8706,7 +8488,7 @@ class binary_reader default: // anything else not supported (yet) { std::array cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + static_cast((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType())); } } @@ -8767,7 +8549,7 @@ class binary_reader std::int32_t document_size{}; get_number(input_format_t::bson, document_size); - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) { return false; } @@ -9026,7 +8808,7 @@ class binary_reader } case 0x9F: // array (indefinite length) - return get_cbor_array(std::size_t(-1), tag_handler); + return get_cbor_array(static_cast(-1), tag_handler); // map (0x00..0x17 pairs of data items follow) case 0xA0: @@ -9080,7 +8862,7 @@ class binary_reader } case 0xBF: // map (indefinite length) - return get_cbor_object(std::size_t(-1), tag_handler); + return get_cbor_object(static_cast(-1), tag_handler); case 0xC6: // tagged item case 0xC7: @@ -9464,7 +9246,7 @@ class binary_reader } /*! - @param[in] len the length of the array or std::size_t(-1) for an + @param[in] len the length of the array or static_cast(-1) for an array of indefinite size @param[in] tag_handler how CBOR tags should be treated @return whether array creation completed @@ -9477,7 +9259,7 @@ class binary_reader return false; } - if (len != std::size_t(-1)) + if (len != static_cast(-1)) { for (std::size_t i = 0; i < len; ++i) { @@ -9502,7 +9284,7 @@ class binary_reader } /*! - @param[in] len the length of the object or std::size_t(-1) for an + @param[in] len the length of the object or static_cast(-1) for an object of indefinite size @param[in] tag_handler how CBOR tags should be treated @return whether object creation completed @@ -9518,7 +9300,7 @@ class binary_reader if (len != 0) { string_t key; - if (len != std::size_t(-1)) + if (len != static_cast(-1)) { for (std::size_t i = 0; i < len; ++i) { @@ -10528,7 +10310,7 @@ class binary_reader } else { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) { return false; } @@ -10598,7 +10380,7 @@ class binary_reader } else { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) { return false; } @@ -10729,7 +10511,7 @@ class binary_reader @return whether conversion completed - @note This function needs to respect the system's endianess, because + @note This function needs to respect the system's endianness, because bytes in CBOR, MessagePack, and UBJSON are stored in network order (big endian) and therefore need reordering on little endian systems. */ @@ -10850,7 +10632,7 @@ class binary_reader std::string get_token_string() const { std::array cr{{}}; - (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + static_cast((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) return std::string{cr.data()}; } @@ -10902,8 +10684,8 @@ class binary_reader /// the number of characters read std::size_t chars_read = 0; - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); + /// whether we can assume little endianness + const bool is_little_endian = little_endianness(); /// the SAX parser json_sax_t* sax = nullptr; @@ -11111,7 +10893,7 @@ class parser { case token_type::begin_object: { - if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) { return false; } @@ -11156,7 +10938,7 @@ class parser case token_type::begin_array: { - if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1)))) + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) { return false; } @@ -11621,7 +11403,7 @@ This class implements a both iterators (iterator and const_iterator) for the iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593) */ template -class iter_impl +class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) { /// the iterator with BasicJsonType of different const-ness using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; @@ -12470,6 +12252,9 @@ class json_reverse_iterator : public std::reverse_iterator namespace nlohmann { + +/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document +/// @sa https://json.nlohmann.me/api/json_pointer/ template class json_pointer { @@ -12478,45 +12263,14 @@ class json_pointer friend class basic_json; public: - /*! - @brief create JSON pointer - - Create a JSON pointer according to the syntax described in - [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3). - - @param[in] s string representing the JSON pointer; if omitted, the empty - string is assumed which references the whole JSON value - - @throw parse_error.107 if the given JSON pointer @a s is nonempty and does - not begin with a slash (`/`); see example below - - @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is - not followed by `0` (representing `~`) or `1` (representing `/`); see - example below - - @liveexample{The example shows the construction several valid JSON pointers - as well as the exceptional behavior.,json_pointer} - - @since version 2.0.0 - */ + /// @brief create JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/ explicit json_pointer(const std::string& s = "") : reference_tokens(split(s)) {} - /*! - @brief return a string representation of the JSON pointer - - @invariant For each JSON pointer `ptr`, it holds: - @code {.cpp} - ptr == json_pointer(ptr.to_string()); - @endcode - - @return a string representation of the JSON pointer - - @liveexample{The example shows the result of `to_string`.,json_pointer__to_string} - - @since version 2.0.0 - */ + /// @brief return a string representation of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/to_string/ std::string to_string() const { return std::accumulate(reference_tokens.begin(), reference_tokens.end(), @@ -12527,28 +12281,15 @@ class json_pointer }); } - /// @copydoc to_string() + /// @brief return a string representation of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/ operator std::string() const { return to_string(); } - /*! - @brief append another JSON pointer at the end of this JSON pointer - - @param[in] ptr JSON pointer to append - @return JSON pointer with @a ptr appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::string) to append a reference token - @sa see @ref operator/=(std::size_t) to append an array index - @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator - - @since version 3.6.0 - */ + /// @brief append another JSON pointer at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ json_pointer& operator/=(const json_pointer& ptr) { reference_tokens.insert(reference_tokens.end(), @@ -12557,123 +12298,45 @@ class json_pointer return *this; } - /*! - @brief append an unescaped reference token at the end of this JSON pointer - - @param[in] token reference token to append - @return JSON pointer with @a token appended without escaping @a token - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - @sa see @ref operator/=(std::size_t) to append an array index - @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator - - @since version 3.6.0 - */ + /// @brief append an unescaped reference token at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ json_pointer& operator/=(std::string token) { push_back(std::move(token)); return *this; } - /*! - @brief append an array index at the end of this JSON pointer - - @param[in] array_idx array index to append - @return JSON pointer with @a array_idx appended - - @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add} - - @complexity Amortized constant. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - @sa see @ref operator/=(std::string) to append a reference token - @sa see @ref operator/(const json_pointer&, std::string) for a binary operator - - @since version 3.6.0 - */ + /// @brief append an array index at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ json_pointer& operator/=(std::size_t array_idx) { return *this /= std::to_string(array_idx); } - /*! - @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer - - @param[in] lhs JSON pointer - @param[in] rhs JSON pointer - @return a new JSON pointer with @a rhs appended to @a lhs - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a lhs and @a rhs. - - @sa see @ref operator/=(const json_pointer&) to append a JSON pointer - - @since version 3.6.0 - */ + /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ friend json_pointer operator/(const json_pointer& lhs, const json_pointer& rhs) { return json_pointer(lhs) /= rhs; } - /*! - @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] token reference token - @return a new JSON pointer with unescaped @a token appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::string) to append a reference token - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param) + /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, std::string token) // NOLINT(performance-unnecessary-value-param) { - return json_pointer(ptr) /= std::move(token); + return json_pointer(lhs) /= std::move(token); } - /*! - @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer - - @param[in] ptr JSON pointer - @param[in] array_idx array index - @return a new JSON pointer with @a array_idx appended to @a ptr - - @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary} - - @complexity Linear in the length of @a ptr. - - @sa see @ref operator/=(std::size_t) to append an array index - - @since version 3.6.0 - */ - friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx) + /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx) { - return json_pointer(ptr) /= array_idx; + return json_pointer(lhs) /= array_idx; } - /*! - @brief returns the parent of this JSON pointer - - @return 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. - - @liveexample{The example shows the result of `parent_pointer` for different - JSON Pointers.,json_pointer__parent_pointer} - - @since version 3.6.0 - */ + /// @brief returns the parent of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/ json_pointer parent_pointer() const { if (empty()) @@ -12686,19 +12349,8 @@ class json_pointer return res; } - /*! - @brief remove last reference token - - @pre not `empty()` - - @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ + /// @brief remove last reference token + /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/ void pop_back() { if (JSON_HEDLEY_UNLIKELY(empty())) @@ -12709,20 +12361,8 @@ class json_pointer reference_tokens.pop_back(); } - /*! - @brief return last reference token - - @pre not `empty()` - @return last reference token - - @liveexample{The example shows the usage of `back`.,json_pointer__back} - - @complexity Constant. - - @throw out_of_range.405 if JSON pointer has no parent - - @since version 3.6.0 - */ + /// @brief return last reference token + /// @sa https://json.nlohmann.me/api/json_pointer/back/ const std::string& back() const { if (JSON_HEDLEY_UNLIKELY(empty())) @@ -12733,43 +12373,22 @@ class json_pointer return reference_tokens.back(); } - /*! - @brief append an unescaped token at the end of the reference pointer - - @param[in] token token to add - - @complexity Amortized constant. - - @liveexample{The example shows the result of `push_back` for different - JSON Pointers.,json_pointer__push_back} - - @since version 3.6.0 - */ + /// @brief append an unescaped token at the end of the reference pointer + /// @sa https://json.nlohmann.me/api/json_pointer/push_back/ void push_back(const std::string& token) { reference_tokens.push_back(token); } - /// @copydoc push_back(const std::string&) + /// @brief append an unescaped token at the end of the reference pointer + /// @sa https://json.nlohmann.me/api/json_pointer/push_back/ void push_back(std::string&& token) { reference_tokens.push_back(std::move(token)); } - /*! - @brief return whether pointer points to the root document - - @return true iff the JSON pointer points to the root document - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example shows the result of `empty` for different JSON - Pointers.,json_pointer__empty} - - @since version 3.6.0 - */ + /// @brief return whether pointer points to the root document + /// @sa https://json.nlohmann.me/api/json_pointer/empty/ bool empty() const noexcept { return reference_tokens.empty(); @@ -14750,7 +14369,7 @@ class binary_writer { std::size_t array_index = 0ul; - const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) + const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el) { return result + calc_bson_element_size(std::to_string(array_index++), el); }); @@ -14794,7 +14413,7 @@ class binary_writer write_bson_entry_header(name, 0x05); write_number(static_cast(value.size())); - write_number(value.has_subtype() ? static_cast(value.subtype()) : std::uint8_t(0x00)); + write_number(value.has_subtype() ? static_cast(value.subtype()) : static_cast(0x00)); oa->write_characters(reinterpret_cast(value.data()), value.size()); } @@ -14900,7 +14519,7 @@ class binary_writer */ static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value) { - std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0), + std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast(0), [](size_t result, const typename BasicJsonType::object_t::value_type & el) { return result += calc_bson_element_size(el.first, el.second); @@ -15202,7 +14821,7 @@ class binary_writer @tparam OutputIsLittleEndian Set to true if output data is required to be little endian - @note This function needs to respect the system's endianess, because bytes + @note This function needs to respect the system's endianness, because bytes in CBOR, MessagePack, and UBJSON are stored in network order (big endian) and therefore need reordering on little endian systems. */ @@ -15292,8 +14911,8 @@ class binary_writer } private: - /// whether we can assume little endianess - const bool is_little_endian = little_endianess(); + /// whether we can assume little endianness + const bool is_little_endian = little_endianness(); /// the output output_adapter_t oa = nullptr; @@ -15315,6 +14934,8 @@ class binary_writer #include // snprintf #include // numeric_limits #include // string, char_traits +#include // setfill, setw +#include // stringstream #include // is_same #include // move @@ -16213,7 +15834,7 @@ void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) // // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars) // says "value is converted to a string as if by std::sprintf in the default ("C") locale" - // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars' + // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars' // does. // On the other hand, the documentation for 'std::to_chars' requires that "parsing the // representation using the corresponding std::from_chars function recovers value exactly". That @@ -16879,16 +16500,16 @@ class serializer if (codepoint <= 0xFFFF) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", - static_cast(codepoint)); + static_cast((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x", + static_cast(codepoint))); bytes += 6; } else { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", - static_cast(0xD7C0u + (codepoint >> 10u)), - static_cast(0xDC00u + (codepoint & 0x3FFu))); + static_cast((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x", + static_cast(0xD7C0u + (codepoint >> 10u)), + static_cast(0xDC00u + (codepoint & 0x3FFu)))); bytes += 12; } } @@ -16923,10 +16544,9 @@ class serializer { case error_handler_t::strict: { - std::string sn(9, '\0'); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(&sn[0], sn.size(), "%.2X", byte); - JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType())); + std::stringstream ss; + ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (byte | 0); + JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str(), BasicJsonType())); } case error_handler_t::ignore: @@ -17018,10 +16638,9 @@ class serializer { case error_handler_t::strict: { - std::string sn(9, '\0'); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast(s.back())); - JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType())); + std::stringstream ss; + ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (static_cast(s.back()) | 0); + JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str(), BasicJsonType())); } case error_handler_t::ignore: @@ -17088,6 +16707,19 @@ class serializer } } + // templates to avoid warnings about useless casts + template ::value, int> = 0> + bool is_negative_number(NumberType x) + { + return x < 0; + } + + template < typename NumberType, enable_if_t ::value, int > = 0 > + bool is_negative_number(NumberType /*unused*/) + { + return false; + } + /*! @brief dump an integer @@ -17131,12 +16763,11 @@ class serializer // use a pointer to fill the buffer auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg) - const bool is_negative = std::is_signed::value && !(x >= 0); // see issue #755 number_unsigned_t abs_value; unsigned int n_chars{}; - if (is_negative) + if (is_negative_number(x)) { *buffer_ptr = '-'; abs_value = remove_sign(static_cast(x)); @@ -17153,7 +16784,7 @@ class serializer // spare 1 byte for '\0' JSON_ASSERT(n_chars < number_buffer.size() - 1); - // jump to the end to generate the string from backward + // jump to the end to generate the string from backward, // so we later avoid reversing the result buffer_ptr += n_chars; @@ -17255,7 +16886,7 @@ class serializer o->write_characters(number_buffer.data(), static_cast(len)); - // determine if need to append ".0" + // determine if we need to append ".0" const bool value_is_int_like = std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1, [](char c) @@ -17410,10 +17041,10 @@ template , using key_type = Key; using mapped_type = T; using Container = std::vector, Allocator>; - using typename Container::iterator; - using typename Container::const_iterator; - using typename Container::size_type; - using typename Container::value_type; + using iterator = typename Container::iterator; + using const_iterator = typename Container::const_iterator; + using size_type = typename Container::size_type; + using value_type = typename Container::value_type; // Explicit constructors instead of `using Container::Container` // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) @@ -17494,16 +17125,55 @@ template , iterator erase(iterator pos) { - auto it = pos; + return erase(pos, std::next(pos)); + } + + iterator erase(iterator first, iterator last) + { + const auto elements_affected = std::distance(first, last); + const auto offset = std::distance(Container::begin(), first); + + // This is the start situation. We need to delete elements_affected + // elements (3 in this example: e, f, g), and need to return an + // iterator past the last deleted element (h in this example). + // Note that offset is the distance from the start of the vector + // to first. We will need this later. - // Since we cannot move const Keys, re-construct them in place - for (auto next = it; ++next != this->end(); ++it) + // [ a, b, c, d, e, f, g, h, i, j ] + // ^ ^ + // first last + + // Since we cannot move const Keys, we re-construct them in place. + // We start at first and re-construct (viz. copy) the elements from + // the back of the vector. Example for first iteration: + + // ,--------. + // v | destroy e and re-construct with h + // [ a, b, c, d, e, f, g, h, i, j ] + // ^ ^ + // it it + elements_affected + + for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it) { - it->~value_type(); // Destroy but keep allocation - new (&*it) value_type{std::move(*next)}; + it->~value_type(); // destroy but keep allocation + new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it } - Container::pop_back(); - return pos; + + // [ a, b, c, d, h, i, j, h, i, j ] + // ^ ^ + // first last + + // remove the unneeded elements at the end of the vector + Container::resize(this->size() - static_cast(elements_affected)); + + // [ a, b, c, d, h, i, j ] + // ^ ^ + // first last + + // first is now pointing past the last deleted element, but we cannot + // use this iterator, because it may have been invalidated by the + // resize call. Instead, we can return begin() + offset. + return Container::begin() + offset; } size_type count(const Key& key) const @@ -17592,69 +17262,7 @@ namespace nlohmann /*! @brief a class to store JSON values -@tparam ObjectType type for JSON objects (`std::map` by default; will be used -in @ref object_t) -@tparam ArrayType type for JSON arrays (`std::vector` by default; will be used -in @ref array_t) -@tparam StringType type for JSON strings and object keys (`std::string` by -default; will be used in @ref string_t) -@tparam BooleanType type for JSON booleans (`bool` by default; will be used -in @ref boolean_t) -@tparam NumberIntegerType type for JSON integer numbers (`int64_t` by -default; will be used in @ref number_integer_t) -@tparam NumberUnsignedType type for JSON unsigned integer numbers (@c -`uint64_t` by default; will be used in @ref number_unsigned_t) -@tparam NumberFloatType type for JSON floating-point numbers (`double` by -default; will be used in @ref number_float_t) -@tparam BinaryType type for packed binary data for compatibility with binary -serialization formats (`std::vector` by default; will be used in -@ref binary_t) -@tparam AllocatorType type of the allocator to use (`std::allocator` by -default) -@tparam JSONSerializer the serializer to resolve internal calls to `to_json()` -and `from_json()` (@ref adl_serializer by default) - -@requirement The class satisfies the following concept requirements: -- Basic - - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible): - JSON values can be default constructed. The result will be a JSON null - value. - - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible): - A JSON value can be constructed from an rvalue argument. - - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible): - A JSON value can be copy-constructed from an lvalue expression. - - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable): - A JSON value van be assigned from an rvalue argument. - - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable): - A JSON value can be copy-assigned from an lvalue expression. - - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible): - JSON values can be destructed. -- Layout - - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType): - JSON values have - [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout): - All non-static data members are private and standard layout types, the - class has no virtual functions or (virtual) base classes. -- Library-wide - - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable): - JSON values can be compared with `==`, see @ref - operator==(const_reference,const_reference). - - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable): - JSON values can be compared with `<`, see @ref - operator<(const_reference,const_reference). - - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable): - Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of - other compatible types, using unqualified function call @ref swap(). - - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer): - JSON values can be compared against `std::nullptr_t` objects which are used - to model the `null` value. -- Container - - [Container](https://en.cppreference.com/w/cpp/named_req/Container): - JSON values can be used like STL containers and provide iterator access. - - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer); - JSON values can be used like STL containers and provide reverse iterator - access. - +@internal @invariant The member variables @a m_value and @a m_type have the following relationship: - If `m_type == value_t::object`, then `m_value.object != nullptr`. @@ -17662,13 +17270,9 @@ and `from_json()` (@ref adl_serializer by default) - If `m_type == value_t::string`, then `m_value.string != nullptr`. The invariants are checked by member function assert_invariant(). -@internal @note ObjectType trick from https://stackoverflow.com/a/9860911 @endinternal -@see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange -Format](https://tools.ietf.org/html/rfc8259) - @since version 1.0.0 @nosubgrouping @@ -17759,17 +17363,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// Classes to implement user-defined exceptions. /// @{ - /// @copydoc detail::exception using exception = detail::exception; - /// @copydoc detail::parse_error using parse_error = detail::parse_error; - /// @copydoc detail::invalid_iterator using invalid_iterator = detail::invalid_iterator; - /// @copydoc detail::type_error using type_error = detail::type_error; - /// @copydoc detail::out_of_range using out_of_range = detail::out_of_range; - /// @copydoc detail::other_error using other_error = detail::other_error; /// @} @@ -17817,46 +17415,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @} - /*! - @brief returns the allocator associated with the container - */ + /// @brief returns the allocator associated with the container + /// @sa https://json.nlohmann.me/api/basic_json/get_allocator/ static allocator_type get_allocator() { return allocator_type(); } - /*! - @brief returns version information on the library - - This function returns a JSON object with information about the library, - including the version number and information on the platform and compiler. - - @return 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](http://semver.org), and `string` (the version string). - - @liveexample{The following code shows an example output of the `meta()` - function.,meta} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @complexity Constant. - - @since 2.1.0 - */ + /// @brief returns version information on the library + /// @sa https://json.nlohmann.me/api/basic_json/meta/ JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json meta() { basic_json result; - result["copyright"] = "(C) 2013-2021 Niels Lohmann"; + result["copyright"] = "(C) 2013-2022 Niels Lohmann"; result["name"] = "JSON for Modern C++"; result["url"] = "https://github.com/nlohmann/json"; result["version"]["string"] = @@ -17917,6 +17490,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// the template arguments passed to class @ref basic_json. /// @{ + /// @brief object key comparator type + /// @sa https://json.nlohmann.me/api/basic_json/object_comparator_t/ #if defined(JSON_HAS_CPP_14) // Use transparent comparator if possible, combined with perfect forwarding // on find() and count() calls prevents unnecessary string construction. @@ -17925,501 +17500,42 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec using object_comparator_t = std::less; #endif - /*! - @brief a type for an object - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows: - > An object is an unordered collection of zero or more name/value pairs, - > where a name is a string and a value is a string, number, boolean, null, - > object, or array. - - To store objects in C++, a type is defined by the template parameters - described below. - - @tparam ObjectType the container to store objects (e.g., `std::map` or - `std::unordered_map`) - @tparam 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. - @tparam AllocatorType the allocator to use for objects (e.g., - `std::allocator`) - - #### Default type - - With the default values for @a ObjectType (`std::map`), @a StringType - (`std::string`), and @a AllocatorType (`std::allocator`), the default - value for @a object_t is: - - @code {.cpp} - std::map< - std::string, // key_type - basic_json, // value_type - std::less, // key_compare - std::allocator> // allocator_type - > - @endcode - - #### Behavior - - The choice of @a 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 @ref 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](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the object's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON object. - - #### Storage - - Objects are stored as pointers in a @ref basic_json type. That is, for any - access to object values, a pointer of type `object_t*` must be - dereferenced. - - @sa see @ref array_t -- type for an array value - - @since version 1.0.0 - - @note 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](https://tools.ietf.org/html/rfc8259), because any order implements the - specified "unordered" nature of JSON objects. - */ + /// @brief a type for an object + /// @sa https://json.nlohmann.me/api/basic_json/object_t/ using object_t = ObjectType>>; - /*! - @brief a type for an array - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows: - > An array is an ordered sequence of zero or more values. - - To store objects in C++, a type is defined by the template parameters - explained below. - - @tparam ArrayType container type to store arrays (e.g., `std::vector` or - `std::list`) - @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`) - - #### Default type - - With the default values for @a ArrayType (`std::vector`) and @a - AllocatorType (`std::allocator`), the default value for @a array_t is: - - @code {.cpp} - std::vector< - basic_json, // value_type - std::allocator // allocator_type - > - @endcode - - #### Limits - - [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the maximum depth of nesting. - - In this class, the array's limit of nesting is not explicitly constrained. - However, a maximum depth of nesting may be introduced by the compiler or - runtime environment. A theoretical limit can be queried by calling the - @ref max_size function of a JSON array. - - #### Storage - - Arrays are stored as pointers in a @ref basic_json type. That is, for any - access to array values, a pointer of type `array_t*` must be dereferenced. - - @sa see @ref object_t -- type for an object value - - @since version 1.0.0 - */ + /// @brief a type for an array + /// @sa https://json.nlohmann.me/api/basic_json/array_t/ using array_t = ArrayType>; - /*! - @brief a type for a string - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows: - > A string is a sequence of zero or more Unicode characters. - - To store 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. - - @tparam StringType the container to store strings (e.g., `std::string`). - Note this container is used for keys/names in objects, see @ref object_t. - - #### Default type - - With the default values for @a StringType (`std::string`), the default - value for @a string_t is: - - @code {.cpp} - std::string - @endcode - - #### Encoding - - Strings are stored in UTF-8 encoding. Therefore, functions like - `std::string::size()` or `std::string::length()` return the number of - bytes in the string rather than the number of characters or glyphs. - - #### String comparison - - [RFC 8259](https://tools.ietf.org/html/rfc8259) states: - > Software implementations are typically required to test names of object - > members for equality. Implementations that transform the textual - > representation into sequences of Unicode code units and then perform the - > comparison numerically, code unit by code unit, are interoperable in the - > sense that implementations will agree in all cases on equality or - > inequality of two strings. For example, implementations that compare - > strings with escaped characters unconverted may incorrectly find that - > `"a\\b"` and `"a\u005Cb"` are not equal. - - This implementation is interoperable as it does compare strings code unit - by code unit. - - #### Storage - - String values are stored as pointers in a @ref basic_json type. That is, - for any access to string values, a pointer of type `string_t*` must be - dereferenced. - - @since version 1.0.0 - */ + /// @brief a type for a string + /// @sa https://json.nlohmann.me/api/basic_json/string_t/ using string_t = StringType; - /*! - @brief a type for a boolean - - [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a - type which differentiates the two literals `true` and `false`. - - To store objects in C++, a type is defined by the template parameter @a - BooleanType which chooses the type to use. - - #### Default type - - With the default values for @a BooleanType (`bool`), the default value for - @a boolean_t is: - - @code {.cpp} - bool - @endcode - - #### Storage - - Boolean values are stored directly inside a @ref basic_json type. - - @since version 1.0.0 - */ + /// @brief a type for a boolean + /// @sa https://json.nlohmann.me/api/basic_json/boolean_t/ using boolean_t = BooleanType; - /*! - @brief a type for a number (integer) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store integer numbers in C++, a type is defined by the template - parameter @a NumberIntegerType which chooses the type to use. - - #### Default type - - With the default values for @a NumberIntegerType (`int64_t`), the default - value for @a number_integer_t is: - - @code {.cpp} - int64_t - @endcode - - #### 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](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `9223372036854775807` (INT64_MAX) and the minimal integer number - that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers - that are out of range will yield over/underflow when used in a - constructor. During deserialization, too large or small integer numbers - will be automatically be stored as @ref number_unsigned_t or @ref - number_float_t. - - [RFC 8259](https://tools.ietf.org/html/rfc8259) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \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 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 @ref basic_json type. - - @sa see @ref number_float_t -- type for number values (floating-point) - - @sa see @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ + /// @brief a type for a number (integer) + /// @sa https://json.nlohmann.me/api/basic_json/number_integer_t/ using number_integer_t = NumberIntegerType; - /*! - @brief a type for a number (unsigned) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store unsigned integer numbers in C++, a type is defined by the - template parameter @a NumberUnsignedType which chooses the type to use. - - #### Default type - - With the default values for @a NumberUnsignedType (`uint64_t`), the - default value for @a number_unsigned_t is: - - @code {.cpp} - uint64_t - @endcode - - #### 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](https://tools.ietf.org/html/rfc8259) specifies: - > An implementation may set limits on the range and precision of numbers. - - When the default type is used, the maximal integer number that can be - stored is `18446744073709551615` (UINT64_MAX) and the minimal integer - number that can be stored is `0`. Integer numbers that are out of range - will yield over/underflow when used in a constructor. During - deserialization, too large or small integer numbers will be automatically - be stored as @ref number_integer_t or @ref number_float_t. - - [RFC 8259](https://tools.ietf.org/html/rfc8259) further states: - > Note that when such software is used, numbers that are integers and are - > in the range \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 @ref basic_json type. - - @sa see @ref number_float_t -- type for number values (floating-point) - @sa see @ref number_integer_t -- type for number values (integer) - - @since version 2.0.0 - */ + /// @brief a type for a number (unsigned) + /// @sa https://json.nlohmann.me/api/basic_json/number_unsigned_t/ using number_unsigned_t = NumberUnsignedType; - /*! - @brief a type for a number (floating-point) - - [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows: - > The representation of numbers is similar to that used in most - > programming languages. A number is represented in base 10 using decimal - > digits. It contains an integer component that may be prefixed with an - > optional minus sign, which may be followed by a fraction part and/or an - > exponent part. Leading zeros are not allowed. (...) Numeric values that - > cannot be represented in the grammar below (such as Infinity and NaN) - > are not permitted. - - This description includes both integer and floating-point numbers. - However, C++ allows more precise storage if it is known whether the number - is a signed integer, an unsigned integer or a floating-point number. - Therefore, three different types, @ref number_integer_t, @ref - number_unsigned_t and @ref number_float_t are used. - - To store floating-point numbers in C++, a type is defined by the template - parameter @a NumberFloatType which chooses the type to use. - - #### Default type - - With the default values for @a NumberFloatType (`double`), the default - value for @a number_float_t is: - - @code {.cpp} - double - @endcode - - #### 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](https://tools.ietf.org/html/rfc8259) states: - > This specification allows implementations to set limits on the range and - > precision of numbers accepted. Since software that implements IEEE - > 754-2008 binary64 (double precision) numbers is generally available and - > widely used, good interoperability can be achieved by implementations - > that expect no more precision or range than these provide, in the sense - > that implementations will approximate JSON numbers within the expected - > precision. - - This implementation does exactly follow this approach, as it uses double - precision floating-point numbers. Note values smaller than - `-1.79769313486232e+308` and values greater than `1.79769313486232e+308` - will be stored as NaN internally and be serialized to `null`. - - #### Storage - - Floating-point number values are stored directly inside a @ref basic_json - type. - - @sa see @ref number_integer_t -- type for number values (integer) - - @sa see @ref number_unsigned_t -- type for number values (unsigned integer) - - @since version 1.0.0 - */ + /// @brief a type for a number (floating-point) + /// @sa https://json.nlohmann.me/api/basic_json/number_float_t/ using number_float_t = NumberFloatType; - /*! - @brief a type for a packed binary type - - 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::uint8_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). - - [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type - as: - > Major type 2: a byte string. The string's length in bytes is represented - > following the rules for positive integers (major type 0). - - [MessagePack's documentation on the bin type - family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family) - describes this type as: - > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes - > in addition to the size of the byte array. - - [BSON's specifications](http://bsonspec.org/spec.html) describe several - binary types; however, this type is intended to represent the generic binary - type which has the description: - > Generic binary subtype - This is the most commonly used binary subtype and - > should be the 'default' for drivers and tools. - - None of these impose any limitations on the internal representation other - than the basic unit of storage be some type of array whose parts are - decomposable into bytes. - - The default representation of this binary format is a - `std::vector`, which is a very common way to represent a byte - array in modern C++. - - #### Default type - - The default values for @a BinaryType is `std::vector` - - #### Storage - - Binary Arrays are stored as pointers in a @ref 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 serialized - as tagged values. - - 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 singed 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. - - @sa see @ref binary -- create a binary array - - @since version 3.8.0 - */ + /// @brief a type for a packed binary type + /// @sa https://json.nlohmann.me/api/basic_json/binary_t/ using binary_t = nlohmann::byte_container_with_subtype; + /// @} private: @@ -18532,25 +17648,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec case value_t::boolean: { - boolean = boolean_t(false); + boolean = static_cast(false); break; } case value_t::number_integer: { - number_integer = number_integer_t(0); + number_integer = static_cast(0); break; } case value_t::number_unsigned: { - number_unsigned = number_unsigned_t(0); + number_unsigned = static_cast(0); break; } case value_t::number_float: { - number_float = number_float_t(0.0); + number_float = static_cast(0.0); break; } @@ -18566,7 +17682,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec object = nullptr; // silence warning, see #821 if (JSON_HEDLEY_UNLIKELY(t == value_t::null)) { - JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE + JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", basic_json())); // LCOV_EXCL_LINE } break; } @@ -18574,64 +17690,34 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } /// constructor for strings - json_value(const string_t& value) - { - string = create(value); - } + json_value(const string_t& value) : string(create(value)) {} /// constructor for rvalue strings - json_value(string_t&& value) - { - string = create(std::move(value)); - } + json_value(string_t&& value) : string(create(std::move(value))) {} /// constructor for objects - json_value(const object_t& value) - { - object = create(value); - } + json_value(const object_t& value) : object(create(value)) {} /// constructor for rvalue objects - json_value(object_t&& value) - { - object = create(std::move(value)); - } + json_value(object_t&& value) : object(create(std::move(value))) {} /// constructor for arrays - json_value(const array_t& value) - { - array = create(value); - } + json_value(const array_t& value) : array(create(value)) {} /// constructor for rvalue arrays - json_value(array_t&& value) - { - array = create(std::move(value)); - } + json_value(array_t&& value) : array(create(std::move(value))) {} /// constructor for binary arrays - json_value(const typename binary_t::container_type& value) - { - binary = create(value); - } + json_value(const typename binary_t::container_type& value) : binary(create(value)) {} /// constructor for rvalue binary arrays - json_value(typename binary_t::container_type&& value) - { - binary = create(std::move(value)); - } + json_value(typename binary_t::container_type&& value) : binary(create(std::move(value))) {} /// constructor for binary arrays (internal type) - json_value(const binary_t& value) - { - binary = create(value); - } + json_value(const binary_t& value) : binary(create(value)) {} /// constructor for rvalue binary arrays (internal type) - json_value(binary_t&& value) - { - binary = create(std::move(value)); - } + json_value(binary_t&& value) : binary(create(std::move(value))) {} void destroy(value_t t) { @@ -18809,23 +17895,23 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec #endif } - iterator set_parents(iterator it, typename iterator::difference_type count) + iterator set_parents(iterator it, typename iterator::difference_type count_set_parents) { #if JSON_DIAGNOSTICS - for (typename iterator::difference_type i = 0; i < count; ++i) + for (typename iterator::difference_type i = 0; i < count_set_parents; ++i) { (it + i)->m_parent = this; } #else - static_cast(count); + static_cast(count_set_parents); #endif return it; } - reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1)) + reference set_parent(reference j, std::size_t old_capacity = static_cast(-1)) { #if JSON_DIAGNOSTICS - if (old_capacity != std::size_t(-1)) + if (old_capacity != static_cast(-1)) { // see https://github.com/nlohmann/json/issues/2838 JSON_ASSERT(type() == value_t::array); @@ -18865,72 +17951,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // JSON parser callback // ////////////////////////// - /*! - @brief parser event types - - 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 - - @image html callback_events.png "Example when certain parse events are triggered" - - @sa see @ref parser_callback_t for more information and examples - */ + /// @brief parser event types + /// @sa https://json.nlohmann.me/api/basic_json/parse_event_t/ using parse_event_t = detail::parse_event_t; - /*! - @brief per-element parser callback type - - With a parser callback function, the result of parsing a JSON text can be - influenced. When passed to @ref parse, it is called on certain events - (passed as @ref parse_event_t via parameter @a event) with a set recursion - depth @a depth and context JSON value @a 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 @a depth, @a event, and @a parsed. - - parameter @a event | description | parameter @a depth | parameter @a 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 - - @image html callback_events.png "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. - - @param[in] depth the depth of the recursion during parsing - - @param[in] event an event of type parse_event_t indicating the context in - the callback function has been called - - @param[in,out] parsed the current intermediate parse result; note that - writing to this value has no effect for parse_event_t::key events - - @return 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. - - @sa see @ref parse for examples - - @since version 1.0.0 - */ + /// @brief per-element parser callback type + /// @sa https://json.nlohmann.me/api/basic_json/parser_callback_t/ using parser_callback_t = detail::parser_callback_t; ////////////////// @@ -18942,128 +17968,24 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// assignment, static functions creating objects, and the destructor. /// @{ - /*! - @brief create an empty value with a given type - - 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 - - @param[in] v the type of the value to create - - @complexity Constant. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows the constructor for different @ref - value_t values,basic_json__value_t} - - @sa see @ref clear() -- restores the postcondition of this constructor - - @since version 1.0.0 - */ + /// @brief create an empty value with a given type + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ basic_json(const value_t v) : m_type(v), m_value(v) { assert_invariant(); } - /*! - @brief create a null object - - 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. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @liveexample{The following code shows the constructor with and without a - null pointer parameter.,basic_json__nullptr_t} - - @since version 1.0.0 - */ + /// @brief create a null object + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ basic_json(std::nullptr_t = nullptr) noexcept : basic_json(value_t::null) { assert_invariant(); } - /*! - @brief create a JSON value - - 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 @a val to that method (to `json_serializer::to_json` method - with `U = uncvref_t`, to be exact). - - Template type @a CompatibleType includes, but is not limited to, the - following types: - - **arrays**: @ref 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 @ref basic_json value can be constructed. - - **objects**: @ref 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 - @ref string_t and a `value_type` from which a @ref basic_json value can - be constructed. - - **strings**: @ref string_t, string literals, and all compatible string - containers can be used. - - **numbers**: @ref number_integer_t, @ref number_unsigned_t, - @ref number_float_t, and all convertible number types such as `int`, - `size_t`, `int64_t`, `float` or `double` can be used. - - **boolean**: @ref boolean_t / `bool` can be used. - - **binary**: @ref 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. - - @tparam CompatibleType a type such that: - - @a CompatibleType is not derived from `std::istream`, - - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move - constructors), - - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments) - - @a CompatibleType is not a @ref basic_json nested type (e.g., - @ref json_pointer, @ref iterator, etc ...) - - `json_serializer` has a `to_json(basic_json_t&, CompatibleType&&)` method - - @tparam U = `uncvref_t` - - @param[in] val the value to be forwarded to the respective constructor - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety 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. - - @liveexample{The following code shows the constructor with several - compatible types.,basic_json__CompatibleType} - - @since version 2.1.0 - */ + /// @brief create a JSON value from compatible types + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ template < typename CompatibleType, typename U = detail::uncvref_t, detail::enable_if_t < @@ -19077,32 +17999,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec assert_invariant(); } - /*! - @brief create a JSON value from an existing one - - This is a constructor for existing @ref 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 @ref m_value of the parameter. - - @tparam BasicJsonType a type such that: - - @a BasicJsonType is a @ref basic_json type. - - @a BasicJsonType has different template arguments than @ref basic_json_t. - - @param[in] val the @ref basic_json value to be converted. - - @complexity Usually linear in the size of the passed @a val, also - depending on the implementation of the called `to_json()` - method. - - @exceptionsafety 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. - - @since version 3.2.0 - */ + /// @brief create a JSON value from an existing one + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ template < typename BasicJsonType, detail::enable_if_t < detail::is_basic_json::value&& !std::is_same::value, int > = 0 > @@ -19156,80 +18054,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec assert_invariant(); } - /*! - @brief create a container (array or object) from an initializer list - - Creates a JSON value of type array or object from the passed initializer - list @a init. In case @a type_deduction is `true` (default), the type of - the JSON value to be created is deducted from the initializer list @a 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 @ref array(initializer_list_t) - with an empty initializer list in this case - - arrays whose elements satisfy rule 2: use @ref - array(initializer_list_t) with the same initializer list - in this case - - @note When used without parentheses around an empty initializer list, @ref - basic_json() is called instead of this function, yielding the JSON null - value. - - @param[in] init initializer list with JSON values - - @param[in] type_deduction internal parameter; when set to `true`, the type - of the JSON value is deducted from the initializer list @a init; when set - to `false`, the type provided via @a manual_type is forced. This mode is - used by the functions @ref array(initializer_list_t) and - @ref object(initializer_list_t). - - @param[in] manual_type internal parameter; when @a type_deduction is set - to `false`, the created JSON value will use the provided type (only @ref - value_t::array and @ref value_t::object are valid); when @a type_deduction - is set to `true`, this parameter has no effect - - @throw type_error.301 if @a type_deduction is `false`, @a manual_type is - `value_t::object`, but @a 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 @a type_deduction would have be `true`, an array - would have been created. See @ref object(initializer_list_t) - for an example. - - @complexity Linear in the size of the initializer list @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows how JSON values are created from - initializer lists.,basic_json__list_init_t} - - @sa see @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - @sa see @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ + /// @brief create a container (array or object) from an initializer list + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ basic_json(initializer_list_t init, bool type_deduction = true, value_t manual_type = value_t::array) @@ -19283,33 +18109,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec assert_invariant(); } - /*! - @brief explicitly create a binary array (without subtype) - - Creates a JSON binary array value from a given binary container. 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. - - @note 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. - - @param[in] init container containing bytes to use as binary type - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ + /// @brief explicitly create a binary array (without subtype) + /// @sa https://json.nlohmann.me/api/basic_json/binary/ JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json binary(const typename binary_t::container_type& init) { @@ -19319,34 +18120,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res; } - /*! - @brief explicitly create a binary array (with subtype) - - Creates a JSON binary array value from a given binary container. 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. - - @note 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. - - @param[in] init container containing bytes to use as binary type - @param[in] subtype subtype to use in MessagePack and BSON - - @return JSON binary array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @since version 3.8.0 - */ + /// @brief explicitly create a binary array (with subtype) + /// @sa https://json.nlohmann.me/api/basic_json/binary/ JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype) { @@ -19356,7 +18131,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res; } - /// @copydoc binary(const typename binary_t::container_type&) + /// @brief explicitly create a binary array + /// @sa https://json.nlohmann.me/api/basic_json/binary/ JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json binary(typename binary_t::container_type&& init) { @@ -19366,7 +18142,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res; } - /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type) + /// @brief explicitly create a binary array (with subtype) + /// @sa https://json.nlohmann.me/api/basic_json/binary/ JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype) { @@ -19376,115 +18153,24 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res; } - /*! - @brief explicitly create an array from an initializer list - - 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. - - @note This function is only needed to express two edge cases that cannot - be realized with the initializer list constructor (@ref - 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 - - @param[in] init initializer list with JSON values to create an array from - (optional) - - @return JSON array value - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `array` - function.,array} - - @sa see @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa see @ref object(initializer_list_t) -- create a JSON object - value from an initializer list - - @since version 1.0.0 - */ + /// @brief explicitly create an array from an initializer list + /// @sa https://json.nlohmann.me/api/basic_json/array/ JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json array(initializer_list_t init = {}) { return basic_json(init, false, value_t::array); } - /*! - @brief explicitly create an object from an initializer list - - 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. + /// @brief explicitly create an object from an initializer list + /// @sa https://json.nlohmann.me/api/basic_json/object/ + JSON_HEDLEY_WARN_UNUSED_RESULT + static basic_json object(initializer_list_t init = {}) + { + return basic_json(init, false, value_t::object); + } - @note This function is only added for symmetry reasons. In contrast to the - related function @ref array(initializer_list_t), there are - no cases which can only be expressed by this function. That is, any - initializer list @a init can also be passed to the initializer list - constructor @ref basic_json(initializer_list_t, bool, value_t). - - @param[in] init initializer list to create an object from (optional) - - @return JSON object value - - @throw type_error.301 if @a 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 @ref basic_json(initializer_list_t, bool, value_t), - an array would have been created from the passed initializer list @a init. - See example below. - - @complexity Linear in the size of @a init. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows an example for the `object` - function.,object} - - @sa see @ref basic_json(initializer_list_t, bool, value_t) -- - create a JSON value from an initializer list - @sa see @ref array(initializer_list_t) -- create a JSON array - value from an initializer list - - @since version 1.0.0 - */ - JSON_HEDLEY_WARN_UNUSED_RESULT - static basic_json object(initializer_list_t init = {}) - { - return basic_json(init, false, value_t::object); - } - - /*! - @brief construct an array with count copies of given value - - Constructs a JSON array value by creating @a cnt copies of a passed value. - In case @a cnt is `0`, an empty array is created. - - @param[in] cnt the number of JSON copies of @a val to create - @param[in] val the JSON value to copy - - @post `std::distance(begin(),end()) == cnt` holds. - - @complexity Linear in @a cnt. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The following code shows examples for the @ref - basic_json(size_type\, const basic_json&) - constructor.,basic_json__size_type_basic_json} - - @since version 1.0.0 - */ + /// @brief construct an array with count copies of given value + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ basic_json(size_type cnt, const basic_json& val) : m_type(value_t::array) { @@ -19493,61 +18179,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec assert_invariant(); } - /*! - @brief construct a JSON container given an iterator range - - 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), @a first - must be `begin()` and @a 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. - - @tparam InputIT an input iterator type (@ref iterator or @ref - const_iterator) - - @param[in] first begin of the range to copy from (included) - @param[in] last end of the range to copy from (excluded) - - @pre Iterators @a first and @a last must be initialized. **This - precondition is enforced with an assertion (see warning).** If - assertions are switched off, a violation of this precondition yields - undefined behavior. - - @pre Range `[first, last)` is valid. Usually, this precondition cannot be - checked efficiently. Only certain edge cases are detected; see the - description of the exceptions below. A violation of this precondition - yields undefined behavior. - - @warning A precondition is enforced with a runtime assertion that will - result in calling `std::abort` if this precondition is not met. - Assertions can be disabled by defining `NDEBUG` at compile time. - See https://en.cppreference.com/w/cpp/error/assert for more - information. - - @throw invalid_iterator.201 if iterators @a first and @a last are not - compatible (i.e., do not belong to the same JSON value). In this case, - the range `[first, last)` is undefined. - @throw invalid_iterator.204 if iterators @a first and @a last belong to a - primitive type (number, boolean, or string), but @a first does not point - to the first element any more. In this case, the range `[first, last)` is - undefined. See example code below. - @throw invalid_iterator.206 if iterators @a first and @a last belong to a - null value. In this case, the range `[first, last)` is undefined. - - @complexity Linear in distance between @a first and @a last. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @liveexample{The example below shows several ways to create JSON values by - specifying a subrange with iterators.,basic_json__InputIt_InputIt} - - @since version 1.0.0 - */ + /// @brief construct a JSON container given an iterator range + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ template < class InputIT, typename std::enable_if < std::is_same::value || std::is_same::value, int >::type = 0 > @@ -19663,31 +18296,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec std::is_same>::value, int> = 0 > basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {} - /*! - @brief copy constructor - - Creates a copy of a given JSON value. - - @param[in] other the JSON value to copy - - @post `*this == other` - - @complexity Linear in the size of @a other. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes to any JSON value. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - As postcondition, it holds: `other == basic_json(other)`. - - @liveexample{The following code shows an example for the copy - constructor.,basic_json__basic_json} - - @since version 1.0.0 - */ + /// @brief copy constructor + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ basic_json(const basic_json& other) : m_type(other.m_type) { @@ -19754,32 +18364,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec assert_invariant(); } - /*! - @brief move constructor - - Move constructor. Constructs a JSON value with the contents of the given - value @a other using move semantics. It "steals" the resources from @a - other and leaves it as JSON null value. - - @param[in,out] other value to move to this object - - @post `*this` has the same value as @a other before the call. - @post @a other is a JSON null value. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this constructor never throws - exceptions. - - @requirement This function helps `basic_json` satisfying the - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible) - requirements. - - @liveexample{The code below shows the move constructor explicitly called - via std::move.,basic_json__moveconstructor} - - @since version 1.0.0 - */ + /// @brief move constructor + /// @sa https://json.nlohmann.me/api/basic_json/basic_json/ basic_json(basic_json&& other) noexcept : m_type(std::move(other.m_type)), m_value(std::move(other.m_value)) @@ -19795,29 +18381,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec assert_invariant(); } - /*! - @brief copy assignment - - 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. - - @param[in] other value to copy from - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - @liveexample{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.,basic_json__copyassignment} - - @since version 1.0.0 - */ + /// @brief copy assignment + /// @sa https://json.nlohmann.me/api/basic_json/operator=/ basic_json& operator=(basic_json other) noexcept ( std::is_nothrow_move_constructible::value&& std::is_nothrow_move_assignable::value&& @@ -19837,21 +18402,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return *this; } - /*! - @brief destructor - - Destroys the JSON value and frees all allocated memory. - - @complexity Linear. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is linear. - - All stored elements are destroyed and all memory is freed. - - @since version 1.0.0 - */ + /// @brief destructor + /// @sa https://json.nlohmann.me/api/basic_json/~basic_json/ ~basic_json() noexcept { assert_invariant(false); @@ -19869,53 +18421,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// Functions to inspect the type of a JSON value. /// @{ - /*! - @brief serialization - - Serialization function for JSON values. The function tries to mimic - Python's `json.dumps()` function, and currently supports its @a indent - and @a ensure_ascii parameters. - - @param[in] indent 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. - @param[in] indent_char The character to use for indentation if @a indent is - greater than `0`. The default is ` ` (space). - @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters - in the output are escaped with `\uXXXX` sequences, and the result consists - of ASCII characters only. - @param[in] error_handler how to react on decoding errors; there are three - possible values: `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 string containing the serialization of the JSON value - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded and @a error_handler is set to strict - - @note 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 - - @complexity Linear. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @liveexample{The following example shows the effect of different @a indent\, - @a indent_char\, and @a ensure_ascii parameters to the result of the - serialization.,dump} - - @see https://docs.python.org/2/library/json.html#json.dump - - @since version 1.0.0; indentation character @a indent_char, option - @a 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. - */ + /// @brief serialization + /// @sa https://json.nlohmann.me/api/basic_json/dump/ string_t dump(const int indent = -1, const char indent_char = ' ', const bool ensure_ascii = false, @@ -19936,397 +18443,106 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief return the type of the JSON value (explicit) - - Return the type of the JSON value as a value from the @ref value_t - enumeration. - - @return 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 - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `type()` for all JSON - types.,type} - - @sa see @ref operator value_t() -- return the type of the JSON value (implicit) - @sa see @ref type_name() -- return the type as string - - @since version 1.0.0 - */ + /// @brief return the type of the JSON value (explicit) + /// @sa https://json.nlohmann.me/api/basic_json/type/ constexpr value_t type() const noexcept { return m_type; } - /*! - @brief return whether type is primitive - - This function returns true if and only if the JSON type is primitive - (string, number, boolean, or null). - - @return `true` if type is primitive (string, number, boolean, or null), - `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_primitive()` for all JSON - types.,is_primitive} - - @sa see @ref is_structured() -- returns whether JSON value is structured - @sa see @ref is_null() -- returns whether JSON value is `null` - @sa see @ref is_string() -- returns whether JSON value is a string - @sa see @ref is_boolean() -- returns whether JSON value is a boolean - @sa see @ref is_number() -- returns whether JSON value is a number - @sa see @ref is_binary() -- returns whether JSON value is a binary array - - @since version 1.0.0 - */ + /// @brief return whether type is primitive + /// @sa https://json.nlohmann.me/api/basic_json/is_primitive/ constexpr bool is_primitive() const noexcept { return is_null() || is_string() || is_boolean() || is_number() || is_binary(); } - /*! - @brief return whether type is structured - - This function returns true if and only if the JSON type is structured - (array or object). - - @return `true` if type is structured (array or object), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_structured()` for all JSON - types.,is_structured} - - @sa see @ref is_primitive() -- returns whether value is primitive - @sa see @ref is_array() -- returns whether value is an array - @sa see @ref is_object() -- returns whether value is an object - - @since version 1.0.0 - */ + /// @brief return whether type is structured + /// @sa https://json.nlohmann.me/api/basic_json/is_structured/ constexpr bool is_structured() const noexcept { return is_array() || is_object(); } - /*! - @brief return whether value is null - - This function returns true if and only if the JSON value is null. - - @return `true` if type is null, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_null()` for all JSON - types.,is_null} - - @since version 1.0.0 - */ + /// @brief return whether value is null + /// @sa https://json.nlohmann.me/api/basic_json/is_null/ constexpr bool is_null() const noexcept { return m_type == value_t::null; } - /*! - @brief return whether value is a boolean - - This function returns true if and only if the JSON value is a boolean. - - @return `true` if type is boolean, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_boolean()` for all JSON - types.,is_boolean} - - @since version 1.0.0 - */ + /// @brief return whether value is a boolean + /// @sa https://json.nlohmann.me/api/basic_json/is_boolean/ constexpr bool is_boolean() const noexcept { return m_type == value_t::boolean; } - /*! - @brief return whether value is a number - - 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 `true` if type is number (regardless whether integer, unsigned - integer or floating-type), `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number()` for all JSON - types.,is_number} - - @sa see @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ + /// @brief return whether value is a number + /// @sa https://json.nlohmann.me/api/basic_json/is_number/ constexpr bool is_number() const noexcept { return is_number_integer() || is_number_float(); } - /*! - @brief return whether value is an integer number - - This function returns true if and only if the JSON value is a signed or - unsigned integer number. This excludes floating-point values. - - @return `true` if type is an integer or unsigned integer number, `false` - otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_integer()` for all - JSON types.,is_number_integer} - - @sa see @ref is_number() -- check if value is a number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 1.0.0 - */ + /// @brief return whether value is an integer number + /// @sa https://json.nlohmann.me/api/basic_json/is_number_integer/ constexpr bool is_number_integer() const noexcept { return m_type == value_t::number_integer || m_type == value_t::number_unsigned; } - /*! - @brief return whether value is an unsigned integer number - - 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 `true` if type is an unsigned integer number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_unsigned()` for all - JSON types.,is_number_unsigned} - - @sa see @ref is_number() -- check if value is a number - @sa see @ref is_number_integer() -- check if value is an integer or unsigned - integer number - @sa see @ref is_number_float() -- check if value is a floating-point number - - @since version 2.0.0 - */ + /// @brief return whether value is an unsigned integer number + /// @sa https://json.nlohmann.me/api/basic_json/is_number_unsigned/ constexpr bool is_number_unsigned() const noexcept { return m_type == value_t::number_unsigned; } - /*! - @brief return whether value is a floating-point number - - This function returns true if and only if the JSON value is a - floating-point number. This excludes signed and unsigned integer values. - - @return `true` if type is a floating-point number, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_number_float()` for all - JSON types.,is_number_float} - - @sa see @ref is_number() -- check if value is number - @sa see @ref is_number_integer() -- check if value is an integer number - @sa see @ref is_number_unsigned() -- check if value is an unsigned integer - number - - @since version 1.0.0 - */ + /// @brief return whether value is a floating-point number + /// @sa https://json.nlohmann.me/api/basic_json/is_number_float/ constexpr bool is_number_float() const noexcept { return m_type == value_t::number_float; } - /*! - @brief return whether value is an object - - This function returns true if and only if the JSON value is an object. - - @return `true` if type is object, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_object()` for all JSON - types.,is_object} - - @since version 1.0.0 - */ + /// @brief return whether value is an object + /// @sa https://json.nlohmann.me/api/basic_json/is_object/ constexpr bool is_object() const noexcept { return m_type == value_t::object; } - /*! - @brief return whether value is an array - - This function returns true if and only if the JSON value is an array. - - @return `true` if type is array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_array()` for all JSON - types.,is_array} - - @since version 1.0.0 - */ + /// @brief return whether value is an array + /// @sa https://json.nlohmann.me/api/basic_json/is_array/ constexpr bool is_array() const noexcept { return m_type == value_t::array; } - /*! - @brief return whether value is a string - - This function returns true if and only if the JSON value is a string. - - @return `true` if type is string, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_string()` for all JSON - types.,is_string} - - @since version 1.0.0 - */ + /// @brief return whether value is a string + /// @sa https://json.nlohmann.me/api/basic_json/is_string/ constexpr bool is_string() const noexcept { return m_type == value_t::string; } - /*! - @brief return whether value is a binary array - - This function returns true if and only if the JSON value is a binary array. - - @return `true` if type is binary array, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_binary()` for all JSON - types.,is_binary} - - @since version 3.8.0 - */ + /// @brief return whether value is a binary array + /// @sa https://json.nlohmann.me/api/basic_json/is_binary/ constexpr bool is_binary() const noexcept { return m_type == value_t::binary; } - /*! - @brief return whether value is discarded - - This function returns true if and only if the JSON value was discarded - during parsing with a callback function (see @ref parser_callback_t). - - @note 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. - - @return `true` if type is discarded, `false` otherwise. - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies `is_discarded()` for all JSON - types.,is_discarded} - - @since version 1.0.0 - */ + /// @brief return whether value is discarded + /// @sa https://json.nlohmann.me/api/basic_json/is_discarded/ constexpr bool is_discarded() const noexcept { return m_type == value_t::discarded; } - /*! - @brief return the type of the JSON value (implicit) - - Implicitly return the type of the JSON value as a value from the @ref - value_t enumeration. - - @return the type of the JSON value - - @complexity Constant. - - @exceptionsafety No-throw guarantee: this member function never throws - exceptions. - - @liveexample{The following code exemplifies the @ref value_t operator for - all JSON types.,operator__value_t} - - @sa see @ref type() -- return the type of the JSON value (explicit) - @sa see @ref type_name() -- return the type as string - - @since version 1.0.0 - */ + /// @brief return the type of the JSON value (implicit) + /// @sa https://json.nlohmann.me/api/basic_json/operator_value_t/ constexpr operator value_t() const noexcept { return m_type; @@ -20476,32 +18692,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// Direct access to the stored value of a JSON value. /// @{ - /*! - @brief get a pointer value (implicit) - - Implicit pointer access to the internally stored JSON value. No copies are - made. - - @warning Writing data to the pointee of the result yields an undefined - state. - - @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, - @ref number_unsigned_t, or @ref number_float_t. Enforced by a static - assertion. - - @return pointer to the internally stored JSON value if the requested - pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - - @complexity Constant. - - @liveexample{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.,get_ptr} - - @since version 1.0.0 - */ + /// @brief get a pointer value (implicit) + /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/ template::value, int>::type = 0> auto get_ptr() noexcept -> decltype(std::declval().get_impl_ptr(std::declval())) @@ -20510,10 +18702,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return get_impl_ptr(static_cast(nullptr)); } - /*! - @brief get a pointer value (implicit) - @copydoc get_ptr() - */ + /// @brief get a pointer value (implicit) + /// @sa https://json.nlohmann.me/api/basic_json/get_ptr/ template < typename PointerType, typename std::enable_if < std::is_pointer::value&& std::is_const::type>::value, int >::type = 0 > @@ -20752,39 +18942,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return get_ptr(); } - /*! - @brief get a value (explicit) - - Explicit type conversion between the JSON value and a compatible value. - The value is filled into the input parameter by calling the @ref json_serializer - `from_json()` method. - - The function is equivalent to executing - @code {.cpp} - ValueType v; - JSONSerializer::from_json(*this, v); - @endcode - - This overloads is chosen if: - - @a ValueType is not @ref basic_json, - - @ref json_serializer has a `from_json()` method of the form - `void from_json(const basic_json&, ValueType&)`, and - - @tparam ValueType the input parameter type. - - @return the input parameter, allowing chaining calls. - - @throw what @ref json_serializer `from_json()` method throws - - @liveexample{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`.,get_to} - - @since version 3.3.0 - */ + /// @brief get a value (explicit) + /// @sa https://json.nlohmann.me/api/basic_json/get_to/ template < typename ValueType, detail::enable_if_t < !detail::is_basic_json::value&& @@ -20797,7 +18956,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return v; } - // specialization to allow to call get_to with a basic_json value + // specialization to allow calling get_to with a basic_json value // see https://github.com/nlohmann/json/issues/2175 template::value, int>::type = 0> ReferenceType get_ref() @@ -20856,10 +18991,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return get_ref_impl(*this); } - /*! - @brief get a reference value (implicit) - @copydoc get_ref() - */ + /// @brief get a reference value (implicit) + /// @sa https://json.nlohmann.me/api/basic_json/get_ref/ template < typename ReferenceType, typename std::enable_if < std::is_reference::value&& std::is_const::type>::value, int >::type = 0 > @@ -20917,15 +19050,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return get(); } - /*! - @return reference to the binary value - - @throw type_error.302 if the value is not binary - - @sa see @ref is_binary() to check if the value is binary - - @since version 3.8.0 - */ + /// @brief get a binary value + /// @sa https://json.nlohmann.me/api/basic_json/get_binary/ binary_t& get_binary() { if (!is_binary()) @@ -20936,7 +19062,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return *get_ptr(); } - /// @copydoc get_binary() + /// @brief get a binary value + /// @sa https://json.nlohmann.me/api/basic_json/get_binary/ const binary_t& get_binary() const { if (!is_binary()) @@ -20958,32 +19085,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// Access to the JSON value. /// @{ - /*! - @brief access specified array element with bounds checking - - Returns a reference to the element at specified location @a idx, with - bounds checking. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw 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. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__size_type} - */ + /// @brief access specified array element with bounds checking + /// @sa https://json.nlohmann.me/api/basic_json/at/ reference at(size_type idx) { // at only works for arrays @@ -21005,32 +19108,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief access specified array element with bounds checking - - Returns a const reference to the element at specified location @a idx, - with bounds checking. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw 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. - @throw out_of_range.401 if the index @a idx is out of range of the array; - that is, `idx >= size()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 1.0.0 - - @liveexample{The example below shows how array elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__size_type_const} - */ + /// @brief access specified array element with bounds checking + /// @sa https://json.nlohmann.me/api/basic_json/at/ const_reference at(size_type idx) const { // at only works for arrays @@ -21052,36 +19131,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief access specified object element with bounds checking - - Returns a reference to the element at with specified key @a key, with - bounds checking. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw 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. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read and - written using `at()`. It also demonstrates the different exceptions that - can be thrown.,at__object_t_key_type} - */ + /// @brief access specified object element with bounds checking + /// @sa https://json.nlohmann.me/api/basic_json/at/ reference at(const typename object_t::key_type& key) { // at only works for objects @@ -21103,36 +19154,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief access specified object element with bounds checking - - Returns a const reference to the element at with specified key @a key, - with bounds checking. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @throw 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. - @throw out_of_range.403 if the key @a key is is not stored in the object; - that is, `find(key) == end()`. See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Logarithmic in the size of the container. - - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - - @liveexample{The example below shows how object elements can be read using - `at()`. It also demonstrates the different exceptions that can be thrown., - at__object_t_key_type_const} - */ + /// @brief access specified object element with bounds checking + /// @sa https://json.nlohmann.me/api/basic_json/at/ const_reference at(const typename object_t::key_type& key) const { // at only works for objects @@ -21154,31 +19177,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief access specified array element - - Returns a reference to the element at specified location @a idx. - - @note If @a 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. - - @param[in] idx index of the element to access - - @return reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array or null; in that - cases, using the [] operator with an index makes no sense. - - @complexity Constant if @a idx is in the range of the array. Otherwise - linear in `idx - size()`. - - @liveexample{The example below shows how array elements can be read and - written using `[]` operator. Note the addition of `null` - values.,operatorarray__size_type} - - @since version 1.0.0 - */ + /// @brief access specified array element + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ reference operator[](size_type idx) { // implicitly convert null value to an empty array @@ -21223,25 +19223,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this)); } - /*! - @brief access specified array element - - Returns a const reference to the element at specified location @a idx. - - @param[in] idx index of the element to access - - @return const reference to the element at index @a idx - - @throw type_error.305 if the JSON value is not an array; in that case, - using the [] operator with an index makes no sense. - - @complexity Constant. - - @liveexample{The example below shows how array elements can be read using - the `[]` operator.,operatorarray__size_type_const} - - @since version 1.0.0 - */ + /// @brief access specified array element + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ const_reference operator[](size_type idx) const { // const operator[] only works for arrays @@ -21253,33 +19236,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this)); } - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a 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. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - */ + /// @brief access specified object element + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ reference operator[](const typename object_t::key_type& key) { // implicitly convert null value to an empty object @@ -21299,36 +19257,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); } - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.0.0 - */ + /// @brief access specified object element + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ const_reference operator[](const typename object_t::key_type& key) const { // const operator[] only works for objects @@ -21341,33 +19271,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); } - /*! - @brief access specified object element - - Returns a reference to the element at with specified key @a key. - - @note If @a 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. - - @param[in] key key of the element to access - - @return reference to the element at key @a key - - @throw type_error.305 if the JSON value is not an object or null; in that - cases, using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read and - written using the `[]` operator.,operatorarray__key_type} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.1.0 - */ + /// @brief access specified object element + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ template JSON_HEDLEY_NON_NULL(2) reference operator[](T* key) @@ -21389,36 +19294,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); } - /*! - @brief read-only access specified object element - - Returns a const reference to the element at with specified key @a key. No - bounds checking is performed. - - @warning If the element with key @a key does not exist, the behavior is - undefined. - - @param[in] key key of the element to access - - @return const reference to the element at key @a key - - @pre The element with key @a key must exist. **This precondition is - enforced with an assertion.** - - @throw type_error.305 if the JSON value is not an object; in that case, - using the [] operator with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be read using - the `[]` operator.,operatorarray__key_type_const} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref value() for access by value with a default value - - @since version 1.1.0 - */ + /// @brief access specified object element + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ template JSON_HEDLEY_NON_NULL(2) const_reference operator[](T* key) const @@ -21433,57 +19310,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this)); } - /*! - @brief access specified object element with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(key); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const typename object_t::key_type&), this function - does not throw if the given key @a key was not found. - - @note Unlike @ref operator[](const typename object_t::key_type& key), this - function does not implicitly add an element to the position defined by @a - key. This function is furthermore also applicable to const objects. - - @param[in] key key of the element to access - @param[in] default_value the value to return if @a key is not found - - @tparam 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 @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a key - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value} - - @sa see @ref at(const typename object_t::key_type&) for access by reference - with range checking - @sa see @ref operator[](const typename object_t::key_type&) for unchecked - access by reference - - @since version 1.0.0 - */ - // using std::is_convertible in a std::enable_if will fail when using explicit conversions + /// @brief access specified object element with default value + /// @sa https://json.nlohmann.me/api/basic_json/value/ + /// using std::is_convertible in a std::enable_if will fail when using explicit conversions template < class ValueType, typename std::enable_if < detail::is_getable::value && !std::is_same::value, int >::type = 0 > @@ -21505,58 +19334,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this)); } - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const - */ + /// @brief access specified object element with default value + /// @sa https://json.nlohmann.me/api/basic_json/value/ + /// overload for a default value of type const char* string_t value(const typename object_t::key_type& key, const char* default_value) const { return value(key, string_t(default_value)); } - /*! - @brief access specified object element via JSON Pointer with default value - - Returns either a copy of an object's element at the specified key @a key - or a given default value if no element with key @a key exists. - - The function is basically equivalent to executing - @code {.cpp} - try { - return at(ptr); - } catch(out_of_range) { - return default_value; - } - @endcode - - @note Unlike @ref at(const json_pointer&), this function does not throw - if the given key @a key was not found. - - @param[in] ptr a JSON pointer to the element to access - @param[in] default_value the value to return if @a ptr found no value - - @tparam 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 @a key and the default - value @a default_value must be compatible. - - @return copy of the element at key @a key or @a default_value if @a key - is not found - - @throw type_error.302 if @a default_value does not match the type of the - value at @a ptr - @throw type_error.306 if the JSON value is not an object; in that case, - using `value()` with a key makes no sense. - - @complexity Logarithmic in the size of the container. - - @liveexample{The example below shows how object elements can be queried - with a default value.,basic_json__value_ptr} - - @sa see @ref operator[](const json_pointer&) for unchecked access by reference - - @since version 2.0.2 - */ + /// @brief access specified object element via JSON Pointer with default value + /// @sa https://json.nlohmann.me/api/basic_json/value/ template::value, int>::type = 0> ValueType value(const json_pointer& ptr, const ValueType& default_value) const @@ -21578,85 +19365,31 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this)); } - /*! - @brief overload for a default value of type const char* - @copydoc basic_json::value(const json_pointer&, ValueType) const - */ + /// @brief access specified object element via JSON Pointer with default value + /// @sa https://json.nlohmann.me/api/basic_json/value/ + /// overload for a default value of type const char* JSON_HEDLEY_NON_NULL(3) string_t value(const json_pointer& ptr, const char* default_value) const { return value(ptr, string_t(default_value)); } - /*! - @brief access the first element - - 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 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. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on `null` value - - @liveexample{The following code shows an example for `front()`.,front} - - @sa see @ref back() -- access the last element - - @since version 1.0.0 - */ + /// @brief access the first element + /// @sa https://json.nlohmann.me/api/basic_json/front/ reference front() { return *begin(); } - /*! - @copydoc basic_json::front() - */ + /// @brief access the first element + /// @sa https://json.nlohmann.me/api/basic_json/front/ const_reference front() const { return *cbegin(); } - /*! - @brief access the last element - - Returns a reference to the last element in the container. For a JSON - container `c`, the expression `c.back()` is equivalent to - @code {.cpp} - auto tmp = c.end(); - --tmp; - return *tmp; - @endcode - - @return 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. - - @complexity Constant. - - @pre The JSON value must not be `null` (would throw `std::out_of_range`) - or an empty array or object (undefined behavior, **guarded by - assertions**). - @post The JSON value remains unchanged. - - @throw invalid_iterator.214 when called on a `null` value. See example - below. - - @liveexample{The following code shows an example for `back()`.,back} - - @sa see @ref front() -- access the first element - - @since version 1.0.0 - */ + /// @brief access the last element + /// @sa https://json.nlohmann.me/api/basic_json/back/ reference back() { auto tmp = end(); @@ -21664,9 +19397,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return *tmp; } - /*! - @copydoc basic_json::back() - */ + /// @brief access the last element + /// @sa https://json.nlohmann.me/api/basic_json/back/ const_reference back() const { auto tmp = cend(); @@ -21674,52 +19406,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return *tmp; } - /*! - @brief remove element given an iterator - - Removes the element specified by iterator @a pos. The iterator @a pos must - be valid and dereferenceable. Thus the `end()` iterator (which is valid, - but is not dereferenceable) cannot be used as a value for @a pos. - - If called on a primitive type other than `null`, the resulting JSON value - will be `null`. - - @param[in] pos iterator to the element to remove - @return Iterator following the last removed element. If the iterator @a - pos refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.202 if called on an iterator which does not belong - to the current JSON value; example: `"iterator does not fit current - value"` - @throw 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"` - - @complexity The complexity depends on the type: - - objects: amortized constant - - arrays: linear in distance between @a pos and the end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType} - - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ + /// @brief remove element given an iterator + /// @sa https://json.nlohmann.me/api/basic_json/erase/ template < class IteratorType, typename std::enable_if < std::is_same::value || std::is_same::value, int >::type @@ -21789,52 +19477,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief remove elements given an iterator range - - Removes the element specified by the range `[first; last)`. The iterator - @a 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`. - - @param[in] first iterator to the beginning of the range to remove - @param[in] last iterator past the end of the range to remove - @return Iterator following the last removed element. If the iterator @a - second refers to the last element, the `end()` iterator is returned. - - @tparam IteratorType an @ref iterator or @ref const_iterator - - @post Invalidates iterators and references at or after the point of the - erase, including the `end()` iterator. - - @throw type_error.307 if called on a `null` value; example: `"cannot use - erase() with null"` - @throw invalid_iterator.203 if called on iterators which does not belong - to the current JSON value; example: `"iterators do not fit current value"` - @throw 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"` - - @complexity The complexity depends on the type: - - objects: `log(size()) + std::distance(first, last)` - - arrays: linear in the distance between @a first and @a last, plus linear - in the distance between @a last and end of the container - - strings and binary: linear in the length of the member - - other types: constant - - @liveexample{The example shows the result of `erase()` for different JSON - types.,erase__IteratorType_IteratorType} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ + /// @brief remove elements given an iterator range + /// @sa https://json.nlohmann.me/api/basic_json/erase/ template < class IteratorType, typename std::enable_if < std::is_same::value || std::is_same::value, int >::type @@ -21907,35 +19551,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief remove element from a JSON object given a key - - Removes elements from a JSON object with the key value @a key. - - @param[in] key value of the elements to remove - - @return Number of elements removed. If @a ObjectType is the default - `std::map` type, the return value will always be `0` (@a key was not - found) or `1` (@a key was found). - - @post References and iterators to the erased elements are invalidated. - Other references and iterators are not affected. - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - - @complexity `log(size()) + count(key)` - - @liveexample{The example shows the effect of `erase()`.,erase__key_type} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const size_type) -- removes the element from an array at - the given index - - @since version 1.0.0 - */ + /// @brief remove element from a JSON object given a key + /// @sa https://json.nlohmann.me/api/basic_json/erase/ size_type erase(const typename object_t::key_type& key) { // this erase only works for objects @@ -21947,30 +19564,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this)); } - /*! - @brief remove element from a JSON array given an index - - Removes element from a JSON array at the index @a idx. - - @param[in] idx index of the element to remove - - @throw type_error.307 when called on a type other than JSON object; - example: `"cannot use erase() with null"` - @throw out_of_range.401 when `idx >= size()`; example: `"array index 17 - is out of range"` - - @complexity Linear in distance between @a idx and the end of the container. - - @liveexample{The example shows the effect of `erase()`.,erase__size_type} - - @sa see @ref erase(IteratorType) -- removes the element at a given position - @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in - the given range - @sa see @ref erase(const typename object_t::key_type&) -- removes the element - from an object at the given key - - @since version 1.0.0 - */ + /// @brief remove element from a JSON array given an index + /// @sa https://json.nlohmann.me/api/basic_json/erase/ void erase(const size_type idx) { // this erase only works for arrays @@ -21999,30 +19594,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name lookup /// @{ - /*! - @brief find an element in a JSON object - - Finds an element in a JSON object with key equivalent to @a key. If the - element is not found or the JSON value is not an object, end() is - returned. - - @note This method always returns @ref end() when executed on a JSON type - that is not an object. - - @param[in] key key value of the element to search for. - - @return Iterator to an element with key equivalent to @a key. If no such - element is found or the JSON value is not an object, past-the-end (see - @ref end()) iterator is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `find()` is used.,find__key_type} - - @sa see @ref contains(KeyT&&) const -- checks whether a key exists - - @since version 1.0.0 - */ + /// @brief find an element in a JSON object + /// @sa https://json.nlohmann.me/api/basic_json/find/ template iterator find(KeyT&& key) { @@ -22036,10 +19609,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief find an element in a JSON object - @copydoc find(KeyT&&) - */ + /// @brief find an element in a JSON object + /// @sa https://json.nlohmann.me/api/basic_json/find/ template const_iterator find(KeyT&& key) const { @@ -22053,27 +19624,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief returns the number of occurrences of a key in a JSON object - - Returns the number of elements with key @a key. If ObjectType is the - default `std::map` type, the return value will always be `0` (@a key was - not found) or `1` (@a key was found). - - @note This method always returns `0` when executed on a JSON type that is - not an object. - - @param[in] key key value of the element to count - - @return Number of elements with key @a key. If the JSON value is not an - object, the return value will be `0`. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The example shows how `count()` is used.,count} - - @since version 1.0.0 - */ + /// @brief returns the number of occurrences of a key in a JSON object + /// @sa https://json.nlohmann.me/api/basic_json/count/ template size_type count(KeyT&& key) const { @@ -22081,31 +19633,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return is_object() ? m_value.object->count(std::forward(key)) : 0; } - /*! - @brief check the existence of an element in a JSON object - - Check whether an element exists in a JSON object with key equivalent to - @a key. If the element is not found or the JSON value is not an object, - false is returned. - - @note This method always returns false when executed on a JSON type - that is not an object. - - @param[in] key key value to check its existence. - - @return true if an element with specified @a key exists. If no such - element with such key is found or the JSON value is not an object, - false is returned. - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains} - - @sa see @ref find(KeyT&&) -- returns an iterator to an object element - @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer - - @since version 3.6.0 - */ + /// @brief check the existence of an element in a JSON object + /// @sa https://json.nlohmann.me/api/basic_json/contains/ template < typename KeyT, typename std::enable_if < !std::is_same::type, json_pointer>::value, int >::type = 0 > bool contains(KeyT && key) const @@ -22113,32 +19642,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return is_object() && m_value.object->find(std::forward(key)) != m_value.object->end(); } - /*! - @brief check the existence of an element in a JSON object given a JSON pointer - - Check whether the given JSON pointer @a ptr can be resolved in the current - JSON value. - - @note This method can be executed on any JSON value type. - - @param[in] ptr JSON pointer to check its existence. - - @return true if the JSON pointer can be resolved to a stored value, false - otherwise. - - @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - - @complexity Logarithmic in the size of the JSON object. - - @liveexample{The following code shows an example for `contains()`.,contains_json_pointer} - - @sa see @ref contains(KeyT &&) const -- checks the existence of a key - - @since version 3.7.0 - */ + /// @brief check the existence of an element in a JSON object given a JSON pointer + /// @sa https://json.nlohmann.me/api/basic_json/contains/ bool contains(const json_pointer& ptr) const { return ptr.contains(this); @@ -22154,30 +19659,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name iterators /// @{ - /*! - @brief returns an iterator to the first element - - Returns an iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `begin()`.,begin} - - @sa see @ref cbegin() -- returns a const iterator to the beginning - @sa see @ref end() -- returns an iterator to the end - @sa see @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ + /// @brief returns an iterator to the first element + /// @sa https://json.nlohmann.me/api/basic_json/begin/ iterator begin() noexcept { iterator result(this); @@ -22185,39 +19668,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @copydoc basic_json::cbegin() - */ + /// @brief returns an iterator to the first element + /// @sa https://json.nlohmann.me/api/basic_json/begin/ const_iterator begin() const noexcept { return cbegin(); } - /*! - @brief returns a const iterator to the first element - - Returns a const iterator to the first element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator to the first element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).begin()`. - - @liveexample{The following code shows an example for `cbegin()`.,cbegin} - - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref end() -- returns an iterator to the end - @sa see @ref cend() -- returns a const iterator to the end - - @since version 1.0.0 - */ + /// @brief returns a const iterator to the first element + /// @sa https://json.nlohmann.me/api/basic_json/cbegin/ const_iterator cbegin() const noexcept { const_iterator result(this); @@ -22225,30 +19684,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief returns an iterator to one past the last element - - Returns an iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - @liveexample{The following code shows an example for `end()`.,end} - - @sa see @ref cend() -- returns a const iterator to the end - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ + /// @brief returns an iterator to one past the last element + /// @sa https://json.nlohmann.me/api/basic_json/end/ iterator end() noexcept { iterator result(this); @@ -22256,326 +19693,96 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @copydoc basic_json::cend() - */ + /// @brief returns an iterator to one past the last element + /// @sa https://json.nlohmann.me/api/basic_json/end/ const_iterator end() const noexcept { return cend(); } - /*! - @brief returns a const iterator to one past the last element - - Returns a const iterator to one past the last element. - - @image html range-begin-end.svg "Illustration from cppreference.com" - - @return const iterator one past the last element - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).end()`. - - @liveexample{The following code shows an example for `cend()`.,cend} - - @sa see @ref end() -- returns an iterator to the end - @sa see @ref begin() -- returns an iterator to the beginning - @sa see @ref cbegin() -- returns a const iterator to the beginning - - @since version 1.0.0 - */ + /// @brief returns an iterator to one past the last element + /// @sa https://json.nlohmann.me/api/basic_json/cend/ const_iterator cend() const noexcept { const_iterator result(this); result.set_end(); - return result; - } - - /*! - @brief returns an iterator to the reverse-beginning - - Returns an iterator to the reverse-beginning; that is, the last element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(end())`. - - @liveexample{The following code shows an example for `rbegin()`.,rbegin} - - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - reverse_iterator rbegin() noexcept - { - return reverse_iterator(end()); - } - - /*! - @copydoc basic_json::crbegin() - */ - const_reverse_iterator rbegin() const noexcept - { - return crbegin(); - } - - /*! - @brief returns an iterator to the reverse-end - - Returns an iterator to the reverse-end; that is, one before the first - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `reverse_iterator(begin())`. - - @liveexample{The following code shows an example for `rend()`.,rend} - - @sa see @ref crend() -- returns a const reverse iterator to the end - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - reverse_iterator rend() noexcept - { - return reverse_iterator(begin()); - } - - /*! - @copydoc basic_json::crend() - */ - const_reverse_iterator rend() const noexcept - { - return crend(); - } - - /*! - @brief returns a const reverse iterator to the last element - - Returns a const iterator to the reverse-beginning; that is, the last - element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).rbegin()`. - - @liveexample{The following code shows an example for `crbegin()`.,crbegin} - - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref crend() -- returns a const reverse iterator to the end - - @since version 1.0.0 - */ - const_reverse_iterator crbegin() const noexcept - { - return const_reverse_iterator(cend()); - } - - /*! - @brief returns a const reverse iterator to one before the first - - Returns a const reverse iterator to the reverse-end; that is, one before - the first element. - - @image html range-rbegin-rend.svg "Illustration from cppreference.com" - - @complexity Constant. - - @requirement This function helps `basic_json` satisfying the - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer) - requirements: - - The complexity is constant. - - Has the semantics of `const_cast(*this).rend()`. - - @liveexample{The following code shows an example for `crend()`.,crend} - - @sa see @ref rend() -- returns a reverse iterator to the end - @sa see @ref rbegin() -- returns a reverse iterator to the beginning - @sa see @ref crbegin() -- returns a const reverse iterator to the beginning - - @since version 1.0.0 - */ - const_reverse_iterator crend() const noexcept - { - return const_reverse_iterator(cbegin()); - } - - public: - /*! - @brief wrapper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - 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 iterator_wrapper: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - Range-based for loop without iterator proxy: - - @code{cpp} - for (auto it : j_object) - { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; - } - @endcode - - Range-based for loop with iterator proxy: - - @code{cpp} - for (auto it : json::iterator_wrapper(j_object)) - { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; - } - @endcode - - @note When iterating over an array, `key()` will return the index of the - element as string (see example). - - @param[in] ref reference to a JSON value - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the wrapper is used,iterator_wrapper} - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @note The name of this function is not yet final and may change in the - future. - - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use @ref items() instead; - that is, replace `json::iterator_wrapper(j)` with `j.items()`. - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy iterator_wrapper(reference ref) noexcept - { - return ref.items(); + return result; } - /*! - @copydoc iterator_wrapper(reference) - */ - JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) - static iteration_proxy iterator_wrapper(const_reference ref) noexcept + /// @brief returns an iterator to the reverse-beginning + /// @sa https://json.nlohmann.me/api/basic_json/rbegin/ + reverse_iterator rbegin() noexcept { - return ref.items(); + return reverse_iterator(end()); } - /*! - @brief helper to access iterator member functions in range-based for - - This function allows to access @ref iterator::key() and @ref - 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: - - @code{cpp} - for (auto it = j_object.begin(); it != j_object.end(); ++it) + /// @brief returns an iterator to the reverse-beginning + /// @sa https://json.nlohmann.me/api/basic_json/rbegin/ + const_reverse_iterator rbegin() const noexcept { - std::cout << "key: " << it.key() << ", value:" << it.value() << '\n'; + return crbegin(); } - @endcode - - Range-based for loop without `items()` function: - @code{cpp} - for (auto it : j_object) + /// @brief returns an iterator to the reverse-end + /// @sa https://json.nlohmann.me/api/basic_json/rend/ + reverse_iterator rend() noexcept { - // "it" is of type json::reference and has no key() member - std::cout << "value: " << it << '\n'; + return reverse_iterator(begin()); } - @endcode - - Range-based for loop with `items()` function: - @code{cpp} - for (auto& el : j_object.items()) + /// @brief returns an iterator to the reverse-end + /// @sa https://json.nlohmann.me/api/basic_json/rend/ + const_reverse_iterator rend() const noexcept { - std::cout << "key: " << el.key() << ", value:" << el.value() << '\n'; + return crend(); } - @endcode - - The `items()` function also allows to use - [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding) - (C++17): - @code{cpp} - for (auto& [key, val] : j_object.items()) + /// @brief returns a const reverse iterator to the last element + /// @sa https://json.nlohmann.me/api/basic_json/crbegin/ + const_reverse_iterator crbegin() const noexcept { - std::cout << "key: " << key << ", value:" << val << '\n'; + return const_reverse_iterator(cend()); } - @endcode - - @note 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. - @warning Using `items()` on temporary objects is dangerous. Make sure the - object's lifetime exeeds the iteration. See - for more - information. - - @return iteration proxy object wrapping @a ref with an interface to use in - range-based for loops - - @liveexample{The following code shows how the function is used.,items} + /// @brief returns a const reverse iterator to one before the first + /// @sa https://json.nlohmann.me/api/basic_json/crend/ + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(cbegin()); + } - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. + public: + /// @brief wrapper to access iterator member functions in range-based for + /// @sa https://json.nlohmann.me/api/basic_json/items/ + /// @deprecated This function is deprecated since 3.1.0 and will be removed in + /// version 4.0.0 of the library. Please use @ref items() instead; + /// that is, replace `json::iterator_wrapper(j)` with `j.items()`. + JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) + static iteration_proxy iterator_wrapper(reference ref) noexcept + { + return ref.items(); + } - @complexity Constant. + /// @brief wrapper to access iterator member functions in range-based for + /// @sa https://json.nlohmann.me/api/basic_json/items/ + /// @deprecated This function is deprecated since 3.1.0 and will be removed in + /// version 4.0.0 of the library. Please use @ref items() instead; + /// that is, replace `json::iterator_wrapper(j)` with `j.items()`. + JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items()) + static iteration_proxy iterator_wrapper(const_reference ref) noexcept + { + return ref.items(); + } - @since version 3.1.0, structured bindings support since 3.5.0. - */ + /// @brief helper to access iterator member functions in range-based for + /// @sa https://json.nlohmann.me/api/basic_json/items/ iteration_proxy items() noexcept { return iteration_proxy(*this); } - /*! - @copydoc items() - */ + /// @brief helper to access iterator member functions in range-based for + /// @sa https://json.nlohmann.me/api/basic_json/items/ iteration_proxy items() const noexcept { return iteration_proxy(*this); @@ -22591,48 +19798,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name capacity /// @{ - /*! - @brief checks whether the container is empty. - - Checks if a JSON value has no elements (i.e. whether its @ref size is `0`). - - @return 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()` - - @liveexample{The following code uses `empty()` to check if a JSON - object contains any elements.,empty} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `empty()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note 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. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `begin() == end()`. - - @sa see @ref size() -- returns the number of elements - - @since version 1.0.0 - */ + /// @brief checks whether the container is empty. + /// @sa https://json.nlohmann.me/api/basic_json/empty/ bool empty() const noexcept { switch (m_type) @@ -22670,49 +19837,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief returns the number of elements - - Returns the number of elements in a JSON value. - - @return 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() - - @liveexample{The following code calls `size()` on the different value - types.,size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their size() functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @note 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. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of `std::distance(begin(), end())`. - - @sa see @ref empty() -- checks whether the container is empty - @sa see @ref max_size() -- returns the maximal number of elements - - @since version 1.0.0 - */ + /// @brief returns the number of elements + /// @sa https://json.nlohmann.me/api/basic_json/size/ size_type size() const noexcept { switch (m_type) @@ -22750,47 +19876,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief returns the maximum possible number of elements - - 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 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()` - - @liveexample{The following code calls `max_size()` on the different value - types. Note the output is implementation specific.,max_size} - - @complexity Constant, as long as @ref array_t and @ref object_t satisfy - the Container concept; that is, their `max_size()` functions have constant - complexity. - - @iterators No changes. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @requirement This function helps `basic_json` satisfying the - [Container](https://en.cppreference.com/w/cpp/named_req/Container) - requirements: - - The complexity is constant. - - Has the semantics of returning `b.size()` where `b` is the largest - possible JSON value. - - @sa see @ref size() -- returns the number of elements - - @since version 1.0.0 - */ + /// @brief returns the maximum possible number of elements + /// @sa https://json.nlohmann.me/api/basic_json/max_size/ size_type max_size() const noexcept { switch (m_type) @@ -22833,43 +19920,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name modifiers /// @{ - /*! - @brief clears the contents - - Clears the content of a JSON value and resets it to the default value as - if @ref basic_json(value_t) would have been called with the current value - type from @ref type(): - - Value type | initial value - ----------- | ------------- - null | `null` - boolean | `false` - string | `""` - number | `0` - binary | An empty byte vector - object | `{}` - array | `[]` - - @post Has the same effect as calling - @code {.cpp} - *this = basic_json(type()); - @endcode - - @liveexample{The example below shows the effect of `clear()` to different - JSON types.,clear} - - @complexity Linear in the size of the JSON value. - - @iterators All iterators, pointers and references related to this container - are invalidated. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @sa see @ref basic_json(value_t) -- constructor that creates an object with the - same value than calling `clear()` - - @since version 1.0.0 - */ + /// @brief clears the contents + /// @sa https://json.nlohmann.me/api/basic_json/clear/ void clear() noexcept { switch (m_type) @@ -22929,26 +19981,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief add an object to an array - - Appends the given element @a val to the end of the JSON value. If the - function is called on a JSON null value, an empty array is created before - appending @a val. - - @param[in] val the value to add to the JSON array - - @throw type_error.308 when called on a type other than JSON array or - null; example: `"cannot use push_back() with number"` - - @complexity Amortized constant. - - @liveexample{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.,push_back} - - @since version 1.0.0 - */ + /// @brief add an object to an array + /// @sa https://json.nlohmann.me/api/basic_json/push_back/ void push_back(basic_json&& val) { // push_back only works for null objects or arrays @@ -22969,23 +20003,19 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec const auto old_capacity = m_value.array->capacity(); m_value.array->push_back(std::move(val)); set_parent(m_value.array->back(), old_capacity); - // if val is moved from, basic_json move constructor marks it null so we do not call the destructor + // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor } - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ + /// @brief add an object to an array + /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ reference operator+=(basic_json&& val) { push_back(std::move(val)); return *this; } - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ + /// @brief add an object to an array + /// @sa https://json.nlohmann.me/api/basic_json/push_back/ void push_back(const basic_json& val) { // push_back only works for null objects or arrays @@ -23008,36 +20038,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec set_parent(m_value.array->back(), old_capacity); } - /*! - @brief add an object to an array - @copydoc push_back(basic_json&&) - */ + /// @brief add an object to an array + /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ reference operator+=(const basic_json& val) { push_back(val); return *this; } - /*! - @brief add an object to an object - - Inserts the given element @a val to the JSON object. If the function is - called on a JSON null value, an empty object is created before inserting - @a val. - - @param[in] val the value to add to the JSON object - - @throw type_error.308 when called on a type other than JSON object or - null; example: `"cannot use push_back() with number"` - - @complexity Logarithmic in the size of the container, O(log(`size()`)). - - @liveexample{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.,push_back__object_t__value} - - @since version 1.0.0 - */ + /// @brief add an object to an object + /// @sa https://json.nlohmann.me/api/basic_json/push_back/ void push_back(const typename object_t::value_type& val) { // push_back only works for null objects or objects @@ -23059,41 +20069,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec set_parent(res.first->second); } - /*! - @brief add an object to an object - @copydoc push_back(const typename object_t::value_type&) - */ + /// @brief add an object to an object + /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ reference operator+=(const typename object_t::value_type& val) { push_back(val); return *this; } - /*! - @brief add an object to an object - - This function allows to use `push_back` with an initializer list. In case - - 1. the current value is an object, - 2. the initializer list @a init contains only two elements, and - 3. the first element of @a init is a string, - - @a init is converted into an object element and added using - @ref push_back(const typename object_t::value_type&). Otherwise, @a init - is converted to a JSON value and added using @ref push_back(basic_json&&). - - @param[in] init an initializer list - - @complexity Linear in the size of the initializer list @a init. - - @note 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 - https://github.com/nlohmann/json/issues/235 for more information. - - @liveexample{The example shows how initializer lists are treated as - objects when possible.,push_back__initializer_list} - */ + /// @brief add an object to an object + /// @sa https://json.nlohmann.me/api/basic_json/push_back/ void push_back(initializer_list_t init) { if (is_object() && init.size() == 2 && (*init.begin())->is_string()) @@ -23108,39 +20093,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief add an object to an object - @copydoc push_back(initializer_list_t) - */ + /// @brief add an object to an object + /// @sa https://json.nlohmann.me/api/basic_json/operator+=/ reference operator+=(initializer_list_t init) { push_back(init); return *this; } - /*! - @brief add an object to an array - - Creates a JSON value from the passed parameters @a 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 @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return reference to the inserted element - - @throw type_error.311 when called on a type other than JSON array or - null; example: `"cannot use emplace_back() with number"` - - @complexity Amortized constant. - - @liveexample{The example shows how `push_back()` can be used to add - elements to a JSON array. Note how the `null` value was silently converted - to a JSON array.,emplace_back} - - @since version 2.0.8, returns reference since 3.7.0 - */ + /// @brief add an object to an array + /// @sa https://json.nlohmann.me/api/basic_json/emplace_back/ template reference emplace_back(Args&& ... args) { @@ -23164,33 +20126,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return set_parent(m_value.array->back(), old_capacity); } - /*! - @brief add an object to an object if key does not exist - - Inserts a new element into a JSON object constructed in-place with the - given @a 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 @a args. - - @param[in] args arguments to forward to a constructor of @ref basic_json - @tparam Args compatible types to create a @ref basic_json object - - @return 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. - - @throw 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()`)). - - @liveexample{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.,emplace} - - @since version 2.0.8 - */ + /// @brief add an object to an object if key does not exist + /// @sa https://json.nlohmann.me/api/basic_json/emplace/ template std::pair emplace(Args&& ... args) { @@ -23241,28 +20178,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief inserts element - - Inserts element @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] val element to insert - @return iterator pointing to the inserted @a val. - - @throw type_error.309 if called on JSON values other than arrays; - example: `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Constant plus linear in the distance between @a pos and end of - the container. - - @liveexample{The example shows how `insert()` is used.,insert} - - @since version 1.0.0 - */ + /// @brief inserts element into array + /// @sa https://json.nlohmann.me/api/basic_json/insert/ iterator insert(const_iterator pos, const basic_json& val) { // insert only works for arrays @@ -23281,39 +20198,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); } - /*! - @brief inserts element - @copydoc insert(const_iterator, const basic_json&) - */ + /// @brief inserts element into array + /// @sa https://json.nlohmann.me/api/basic_json/insert/ iterator insert(const_iterator pos, basic_json&& val) { return insert(pos, val); } - /*! - @brief inserts elements - - Inserts @a cnt copies of @a val before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] cnt number of copies of @a val to insert - @param[in] val element to insert - @return iterator pointing to the first element inserted, or @a pos if - `cnt==0` - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @complexity Linear in @a cnt plus linear in the distance between @a pos - and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__count} - - @since version 1.0.0 - */ + /// @brief inserts copies of element into array + /// @sa https://json.nlohmann.me/api/basic_json/insert/ iterator insert(const_iterator pos, size_type cnt, const basic_json& val) { // insert only works for arrays @@ -23332,36 +20225,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this)); } - /*! - @brief inserts elements - - Inserts elements from range `[first, last)` before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - @throw invalid_iterator.211 if @a first or @a last are iterators into - container for which insert is called; example: `"passed iterators may not - belong to container"` - - @return iterator pointing to the first element inserted, or @a pos if - `first==last` - - @complexity Linear in `std::distance(first, last)` plus linear in the - distance between @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__range} - - @since version 1.0.0 - */ + /// @brief inserts range of elements into array + /// @sa https://json.nlohmann.me/api/basic_json/insert/ iterator insert(const_iterator pos, const_iterator first, const_iterator last) { // insert only works for arrays @@ -23391,30 +20256,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator); } - /*! - @brief inserts elements - - Inserts elements from initializer list @a ilist before iterator @a pos. - - @param[in] pos iterator before which the content will be inserted; may be - the end() iterator - @param[in] ilist initializer list to insert the values from - - @throw type_error.309 if called on JSON values other than arrays; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if @a pos is not an iterator of *this; - example: `"iterator does not fit current value"` - - @return iterator pointing to the first element inserted, or @a pos if - `ilist` is empty - - @complexity Linear in `ilist.size()` plus linear in the distance between - @a pos and end of the container. - - @liveexample{The example shows how `insert()` is used.,insert__ilist} - - @since version 1.0.0 - */ + /// @brief inserts elements from initializer list into array + /// @sa https://json.nlohmann.me/api/basic_json/insert/ iterator insert(const_iterator pos, initializer_list_t ilist) { // insert only works for arrays @@ -23433,29 +20276,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return insert_iterator(pos, ilist.begin(), ilist.end()); } - /*! - @brief inserts elements - - Inserts elements from range `[first, last)`. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.309 if called on JSON values other than objects; example: - `"cannot use insert() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` - - @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number - of elements to insert. - - @liveexample{The example shows how `insert()` is used.,insert__range_object} - - @since version 3.0.0 - */ + /// @brief inserts range of elements into object + /// @sa https://json.nlohmann.me/api/basic_json/insert/ void insert(const_iterator first, const_iterator last) { // insert only works for objects @@ -23468,91 +20290,27 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object)) { JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this)); - } - - // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) - { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this)); - } - - m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator); - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from JSON object @a j and overwrites existing keys. - - @param[in] j JSON object to read values from - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. - - @liveexample{The example shows how `update()` is used.,update} - - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update - - @since version 3.0.0 - */ - void update(const_reference j) - { - // implicitly convert null value to an empty object - if (is_null()) - { - m_type = value_t::object; - m_value.object = create(); - assert_invariant(); - } - - if (JSON_HEDLEY_UNLIKELY(!is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this)); - } - if (JSON_HEDLEY_UNLIKELY(!j.is_object())) - { - JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this)); - } - - for (auto it = j.cbegin(); it != j.cend(); ++it) - { - m_value.object->operator[](it.key()) = it.value(); -#if JSON_DIAGNOSTICS - m_value.object->operator[](it.key()).m_parent = this; -#endif - } - } - - /*! - @brief updates a JSON object from another object, overwriting existing keys - - Inserts all values from from range `[first, last)` and overwrites existing - keys. - - @param[in] first begin of the range of elements to insert - @param[in] last end of the range of elements to insert - - @throw type_error.312 if called on JSON values other than objects; example: - `"cannot use update() with string"` - @throw invalid_iterator.202 if iterator @a first or @a last does does not - point to an object; example: `"iterators first and last must point to - objects"` - @throw invalid_iterator.210 if @a first and @a last do not belong to the - same JSON value; example: `"iterators do not fit"` + } - @complexity O(N*log(size() + N)), where N is the number of elements to - insert. + // passed iterators must belong to objects + if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) + { + JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this)); + } - @liveexample{The example shows how `update()` is used__range.,update} + m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator); + } - @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update + /// @brief updates a JSON object from another object, overwriting existing keys + /// @sa https://json.nlohmann.me/api/basic_json/update/ + void update(const_reference j, bool merge_objects = false) + { + update(j.begin(), j.end(), merge_objects); + } - @since version 3.0.0 - */ - void update(const_iterator first, const_iterator last) + /// @brief updates a JSON object from another object, overwriting existing keys + /// @sa https://json.nlohmann.me/api/basic_json/update/ + void update(const_iterator first, const_iterator last, bool merge_objects = false) { // implicitly convert null value to an empty object if (is_null()) @@ -23574,14 +20332,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } // passed iterators must belong to objects - if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object() - || !last.m_object->is_object())) + if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object())) { - JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this)); + JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(first.m_object->type_name()), *first.m_object)); } for (auto it = first; it != last; ++it) { + if (merge_objects && it.value().is_object()) + { + auto it2 = m_value.object->find(it.key()); + if (it2 != m_value.object->end()) + { + it2->second.update(it.value(), true); + continue; + } + } m_value.object->operator[](it.key()) = it.value(); #if JSON_DIAGNOSTICS m_value.object->operator[](it.key()).m_parent = this; @@ -23589,23 +20355,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value with those of @a 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. - - @param[in,out] other JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ + /// @brief exchanges the values + /// @sa https://json.nlohmann.me/api/basic_json/swap/ void swap(reference other) noexcept ( std::is_nothrow_move_constructible::value&& std::is_nothrow_move_assignable::value&& @@ -23621,24 +20372,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec assert_invariant(); } - /*! - @brief exchanges the values - - Exchanges the contents of the JSON value from @a left with those of @a 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. - - @param[in,out] left JSON value to exchange the contents with - @param[in,out] right JSON value to exchange the contents with - - @complexity Constant. - - @liveexample{The example below shows how JSON values can be swapped with - `swap()`.,swap__reference} - - @since version 1.0.0 - */ + /// @brief exchanges the values + /// @sa https://json.nlohmann.me/api/basic_json/swap/ friend void swap(reference left, reference right) noexcept ( std::is_nothrow_move_constructible::value&& std::is_nothrow_move_assignable::value&& @@ -23649,26 +20384,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec left.swap(right); } - /*! - @brief exchanges the values - - Exchanges the contents of a JSON array with those of @a 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. - - @param[in,out] other array to exchange the contents with - - @throw type_error.310 when JSON value is not an array; example: `"cannot - use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how arrays can be swapped with - `swap()`.,swap__array_t} - - @since version 1.0.0 - */ + /// @brief exchanges the values + /// @sa https://json.nlohmann.me/api/basic_json/swap/ void swap(array_t& other) // NOLINT(bugprone-exception-escape) { // swap only works for arrays @@ -23682,26 +20399,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief exchanges the values - - Exchanges the contents of a JSON object with those of @a 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. - - @param[in,out] other object to exchange the contents with - - @throw type_error.310 when JSON value is not an object; example: - `"cannot use swap() with string"` - - @complexity Constant. - - @liveexample{The example below shows how objects can be swapped with - `swap()`.,swap__object_t} - - @since version 1.0.0 - */ + /// @brief exchanges the values + /// @sa https://json.nlohmann.me/api/basic_json/swap/ void swap(object_t& other) // NOLINT(bugprone-exception-escape) { // swap only works for objects @@ -23715,26 +20414,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a 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. - - @param[in,out] other string to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__string_t} - - @since version 1.0.0 - */ + /// @brief exchanges the values + /// @sa https://json.nlohmann.me/api/basic_json/swap/ void swap(string_t& other) // NOLINT(bugprone-exception-escape) { // swap only works for strings @@ -23748,26 +20429,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /*! - @brief exchanges the values - - Exchanges the contents of a JSON string with those of @a 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. - - @param[in,out] other binary to exchange the contents with - - @throw type_error.310 when JSON value is not a string; example: `"cannot - use swap() with boolean"` - - @complexity Constant. - - @liveexample{The example below shows how strings can be swapped with - `swap()`.,swap__binary_t} - - @since version 3.8.0 - */ + /// @brief exchanges the values + /// @sa https://json.nlohmann.me/api/basic_json/swap/ void swap(binary_t& other) // NOLINT(bugprone-exception-escape) { // swap only works for strings @@ -23781,7 +20444,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } } - /// @copydoc swap(binary_t&) + /// @brief exchanges the values + /// @sa https://json.nlohmann.me/api/basic_json/swap/ void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape) { // swap only works for strings @@ -23805,61 +20469,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name lexicographical comparison operators /// @{ - /*! - @brief comparison: equal - - Compares two JSON values for equality according to the following rules: - - Two JSON values are equal if (1) they are from the same type and (2) - their stored values are the same according to their respective - `operator==`. - - Integer and floating-point numbers are automatically converted before - comparison. Note that two NaN values are always treated as unequal. - - Two JSON null values are equal. - - @note Floating-point inside JSON values numbers are compared with - `json::number_float_t::operator==` which is `double::operator==` by - default. To compare floating-point while respecting an epsilon, an alternative - [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39) - could be used, for instance - @code {.cpp} - template::value, T>::type> - inline bool is_same(T a, T b, T epsilon = std::numeric_limits::epsilon()) noexcept - { - return std::abs(a - b) <= epsilon; - } - @endcode - Or you can self-defined operator equal function like this: - @code {.cpp} - bool my_equal(const_reference lhs, const_reference rhs) { - const auto lhs_type lhs.type(); - const auto rhs_type rhs.type(); - if (lhs_type == rhs_type) { - switch(lhs_type) - // self_defined case - case value_t::number_float: - return std::abs(lhs - rhs) <= std::numeric_limits::epsilon(); - // other cases remain the same with the original - ... - } - ... - } - @endcode - - @note NaN values never compare equal to themselves or to other NaN values. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are equal - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Linear. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__equal} - - @since version 1.0.0 - */ + /// @brief comparison: equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ friend bool operator==(const_reference lhs, const_reference rhs) noexcept { #ifdef __GNUC__ @@ -23936,10 +20547,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec #endif } - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ + /// @brief comparison: equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ template::value, int>::type = 0> friend bool operator==(const_reference lhs, ScalarType rhs) noexcept @@ -23947,10 +20556,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return lhs == basic_json(rhs); } - /*! - @brief comparison: equal - @copydoc operator==(const_reference, const_reference) - */ + /// @brief comparison: equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_eq/ template::value, int>::type = 0> friend bool operator==(ScalarType lhs, const_reference rhs) noexcept @@ -23958,33 +20565,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return basic_json(lhs) == rhs; } - /*! - @brief comparison: not equal - - Compares two JSON values for inequality by calculating `not (lhs == rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether the values @a lhs and @a rhs are not equal - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__notequal} - - @since version 1.0.0 - */ + /// @brief comparison: not equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/ friend bool operator!=(const_reference lhs, const_reference rhs) noexcept { return !(lhs == rhs); } - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ + /// @brief comparison: not equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/ template::value, int>::type = 0> friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept @@ -23992,10 +20581,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return lhs != basic_json(rhs); } - /*! - @brief comparison: not equal - @copydoc operator!=(const_reference, const_reference) - */ + /// @brief comparison: not equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_ne/ template::value, int>::type = 0> friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept @@ -24003,32 +20590,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return basic_json(lhs) != rhs; } - /*! - @brief comparison: less than - - Compares whether one JSON value @a lhs is less than another JSON value @a - rhs according to the following rules: - - If @a lhs and @a rhs have the same type, the values are compared using - the default `<` operator. - - Integer and floating-point numbers are automatically converted before - comparison - - In case @a lhs and @a rhs have different types, the values are ignored - and the order of the types is considered, see - @ref operator<(const value_t, const value_t). - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__less} - - @since version 1.0.0 - */ + /// @brief comparison: less than + /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/ friend bool operator<(const_reference lhs, const_reference rhs) noexcept { const auto lhs_type = lhs.type(); @@ -24103,10 +20666,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return operator<(lhs_type, rhs_type); } - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ + /// @brief comparison: less than + /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/ template::value, int>::type = 0> friend bool operator<(const_reference lhs, ScalarType rhs) noexcept @@ -24114,10 +20675,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return lhs < basic_json(rhs); } - /*! - @brief comparison: less than - @copydoc operator<(const_reference, const_reference) - */ + /// @brief comparison: less than + /// @sa https://json.nlohmann.me/api/basic_json/operator_lt/ template::value, int>::type = 0> friend bool operator<(ScalarType lhs, const_reference rhs) noexcept @@ -24125,34 +20684,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return basic_json(lhs) < rhs; } - /*! - @brief comparison: less than or equal - - Compares whether one JSON value @a lhs is less than or equal to another - JSON value by calculating `not (rhs < lhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is less than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greater} - - @since version 1.0.0 - */ + /// @brief comparison: less than or equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ friend bool operator<=(const_reference lhs, const_reference rhs) noexcept { return !(rhs < lhs); } - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ + /// @brief comparison: less than or equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ template::value, int>::type = 0> friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept @@ -24160,10 +20700,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return lhs <= basic_json(rhs); } - /*! - @brief comparison: less than or equal - @copydoc operator<=(const_reference, const_reference) - */ + /// @brief comparison: less than or equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_le/ template::value, int>::type = 0> friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept @@ -24171,34 +20709,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return basic_json(lhs) <= rhs; } - /*! - @brief comparison: greater than - - Compares whether one JSON value @a lhs is greater than another - JSON value by calculating `not (lhs <= rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__lessequal} - - @since version 1.0.0 - */ + /// @brief comparison: greater than + /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/ friend bool operator>(const_reference lhs, const_reference rhs) noexcept { return !(lhs <= rhs); } - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ + /// @brief comparison: greater than + /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/ template::value, int>::type = 0> friend bool operator>(const_reference lhs, ScalarType rhs) noexcept @@ -24206,10 +20725,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return lhs > basic_json(rhs); } - /*! - @brief comparison: greater than - @copydoc operator>(const_reference, const_reference) - */ + /// @brief comparison: greater than + /// @sa https://json.nlohmann.me/api/basic_json/operator_gt/ template::value, int>::type = 0> friend bool operator>(ScalarType lhs, const_reference rhs) noexcept @@ -24217,34 +20734,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return basic_json(lhs) > rhs; } - /*! - @brief comparison: greater than or equal - - Compares whether one JSON value @a lhs is greater than or equal to another - JSON value by calculating `not (lhs < rhs)`. - - @param[in] lhs first JSON value to consider - @param[in] rhs second JSON value to consider - @return whether @a lhs is greater than or equal to @a rhs - - @complexity Linear. - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @liveexample{The example demonstrates comparing several JSON - types.,operator__greaterequal} - - @since version 1.0.0 - */ + /// @brief comparison: greater than or equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ friend bool operator>=(const_reference lhs, const_reference rhs) noexcept { return !(lhs < rhs); } - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ + /// @brief comparison: greater than or equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ template::value, int>::type = 0> friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept @@ -24252,10 +20750,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return lhs >= basic_json(rhs); } - /*! - @brief comparison: greater than or equal - @copydoc operator>=(const_reference, const_reference) - */ + /// @brief comparison: greater than or equal + /// @sa https://json.nlohmann.me/api/basic_json/operator_ge/ template::value, int>::type = 0> friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept @@ -24272,37 +20768,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name serialization /// @{ #ifndef JSON_NO_IO - /*! - @brief serialize to stream - - Serialize the given JSON value @a j to the output stream @a o. The JSON - value will be serialized using the @ref dump member function. - - - The indentation of the output can be controlled with the member variable - `width` of the output stream @a o. For instance, using the manipulator - `std::setw(4)` on @a 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 @a o. For instance, the manipulator - `std::setfill('\\t')` sets indentation to use a tab character rather than - the default space character. - - @param[in,out] o stream to serialize to - @param[in] j JSON value to serialize - - @return the stream @a o - - @throw type_error.316 if a string stored inside the JSON value is not - UTF-8 encoded - - @complexity Linear. - - @liveexample{The example below shows the serialization with different - parameters to `width` to adjust the indentation level.,operator_serialize} - - @since version 1.0.0; indentation character added in version 3.0.0 - */ + /// @brief serialize to stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ friend std::ostream& operator<<(std::ostream& o, const basic_json& j) { // read width member and use it as indentation parameter if nonzero @@ -24318,14 +20785,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return o; } - /*! - @brief serialize to stream - @deprecated This stream operator is deprecated and will be removed in - future 4.0.0 of the library. Please use - @ref operator<<(std::ostream&, const basic_json&) - instead; that is, replace calls like `j >> o;` with `o << j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ + /// @brief serialize to stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ + /// @deprecated This function is deprecated since 3.0.0 and will be removed in + /// version 4.0.0 of the library. Please use + /// operator<<(std::ostream&, const basic_json&) instead; that is, + /// replace calls like `j >> o;` with `o << j;`. JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&)) friend std::ostream& operator>>(const basic_json& j, std::ostream& o) { @@ -24342,57 +20807,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name deserialization /// @{ - /*! - @brief deserialize from a compatible input - - @tparam 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. - - @param[in] i input to read from - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @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 - @a cb or reading from the input @a i has a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `parse()` function reading - from an array.,parse__array__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__string__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function with - and without callback function.,parse__istream__parser_callback_t} - - @liveexample{The example below demonstrates the `parse()` function reading - from a contiguous container.,parse__contiguouscontainer__parser_callback_t} - - @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to - ignore comments. - */ + /// @brief deserialize from a compatible input + /// @sa https://json.nlohmann.me/api/basic_json/parse/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json parse(InputType&& i, @@ -24405,32 +20821,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief deserialize from a pair of character iterators - - The value_type of the iterator must be a integral type with size of 1, 2 or - 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32. - - @param[in] first iterator to start of character range - @param[in] last iterator to end of character range - @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values - (optional) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - */ + /// @brief deserialize from a pair of character iterators + /// @sa https://json.nlohmann.me/api/basic_json/parse/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json parse(IteratorType first, @@ -24456,36 +20848,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief check if the input is valid JSON - - Unlike the @ref parse(InputType&&, const parser_callback_t,const bool) - function, this function neither throws an exception in case of invalid JSON - input (i.e., a parse error) nor creates diagnostic information. - - @tparam 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. - - @param[in] i input to read from - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default) - - @return Whether the input read from @a i is valid JSON. - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `accept()` function reading - from a string.,accept__string} - */ + /// @brief check if the input is valid JSON + /// @sa https://json.nlohmann.me/api/basic_json/accept/ template static bool accept(InputType&& i, const bool ignore_comments = false) @@ -24493,6 +20857,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return parser(detail::input_adapter(std::forward(i)), nullptr, false, ignore_comments).accept(true); } + /// @brief check if the input is valid JSON + /// @sa https://json.nlohmann.me/api/basic_json/accept/ template static bool accept(IteratorType first, IteratorType last, const bool ignore_comments = false) @@ -24508,46 +20874,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return parser(i.get(), nullptr, false, ignore_comments).accept(true); } - /*! - @brief generate SAX events - - The SAX event lister must follow the interface of @ref json_sax. - - This function reads from a compatible input. Examples are: - - 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. - - @param[in] i input to read from - @param[in,out] sax SAX event listener - @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON) - @param[in] strict whether the input has to be consumed completely - @param[in] ignore_comments whether comments should be ignored and treated - like whitespace (true) or yield a parse error (true); (optional, false by - default); only applies to the JSON file format. - - @return return value of the last processed SAX event - - @throw parse_error.101 if a parse error occurs; example: `""unexpected end - of input; expected string literal""` - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @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 @a sax has - a super-linear complexity. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below demonstrates the `sax_parse()` function - reading from string and processing the events with a user-defined SAX - event consumer.,sax_parse} - - @since version 3.2.0 - */ + /// @brief generate SAX events + /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ template JSON_HEDLEY_NON_NULL(2) static bool sax_parse(InputType&& i, SAX* sax, @@ -24561,6 +20889,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); } + /// @brief generate SAX events + /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ template JSON_HEDLEY_NON_NULL(3) static bool sax_parse(IteratorType first, IteratorType last, SAX* sax, @@ -24574,6 +20904,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); } + /// @brief generate SAX events + /// @sa https://json.nlohmann.me/api/basic_json/sax_parse/ + /// @deprecated This function is deprecated since 3.8.0 and will be removed in + /// version 4.0.0 of the library. Please use + /// sax_parse(ptr, ptr + len) instead. template JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...)) JSON_HEDLEY_NON_NULL(2) @@ -24585,50 +20920,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec auto ia = i.get(); return format == input_format_t::json // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) - // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) - : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); - } -#ifndef JSON_NO_IO - /*! - @brief deserialize from stream - @deprecated This stream operator is deprecated and will be removed in - version 4.0.0 of the library. Please use - @ref operator>>(std::istream&, basic_json&) - instead; that is, replace calls like `j << i;` with `i >> j;`. - @since version 1.0.0; deprecated since version 3.0.0 - */ - JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&)) - friend std::istream& operator<<(basic_json& j, std::istream& i) - { - return operator>>(i, j); - } - - /*! - @brief deserialize from stream - - Deserializes an input stream to a JSON value. - - @param[in,out] i input stream to read a serialized JSON value from - @param[in,out] j JSON value to write the deserialized input to - - @throw parse_error.101 in case of an unexpected token - @throw parse_error.102 if to_unicode fails or surrogate error - @throw parse_error.103 if to_unicode fails - - @complexity Linear in the length of the input. The parser is a predictive - LL(1) parser. - - @note A UTF-8 byte order mark is silently ignored. - - @liveexample{The example below shows how a JSON value is constructed by - reading a serialization from a stream.,operator_deserialize} - - @sa parse(std::istream&, const parser_callback_t) for a variant with a - parser callback function to filter values while parsing + ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict) + // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) + : detail::binary_reader(std::move(ia)).sax_parse(format, sax, strict); + } +#ifndef JSON_NO_IO + /// @brief deserialize from stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/ + /// @deprecated This stream operator is deprecated since 3.0.0 and will be removed in + /// version 4.0.0 of the library. Please use + /// operator>>(std::istream&, basic_json&) instead; that is, + /// replace calls like `j << i;` with `i >> j;`. + JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&)) + friend std::istream& operator<<(basic_json& j, std::istream& i) + { + return operator>>(i, j); + } - @since version 1.0.0 - */ + /// @brief deserialize from stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/ friend std::istream& operator>>(std::istream& i, basic_json& j) { parser(detail::input_adapter(i)).parse(false, j); @@ -24641,63 +20951,32 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // convenience functions // /////////////////////////// - /*! - @brief return the type as string - - 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 a string representation of a the @a m_type member: - Value type | return value - ----------- | ------------- - null | `"null"` - boolean | `"boolean"` - string | `"string"` - number | `"number"` (for all number types) - object | `"object"` - array | `"array"` - binary | `"binary"` - discarded | `"discarded"` - - @exceptionsafety No-throw guarantee: this function never throws exceptions. - - @complexity Constant. - - @liveexample{The following code exemplifies `type_name()` for all JSON - types.,type_name} - - @sa see @ref type() -- return the type of the JSON value - @sa see @ref operator value_t() -- return the type of the JSON value (implicit) - - @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept` - since 3.0.0 - */ + /// @brief return the type as string + /// @sa https://json.nlohmann.me/api/basic_json/type_name/ JSON_HEDLEY_RETURNS_NON_NULL const char* type_name() const noexcept { + switch (m_type) { - switch (m_type) - { - case value_t::null: - return "null"; - case value_t::object: - return "object"; - case value_t::array: - return "array"; - case value_t::string: - return "string"; - case value_t::boolean: - return "boolean"; - case value_t::binary: - return "binary"; - case value_t::discarded: - return "discarded"; - case value_t::number_integer: - case value_t::number_unsigned: - case value_t::number_float: - default: - return "number"; - } + case value_t::null: + return "null"; + case value_t::object: + return "object"; + case value_t::array: + return "array"; + case value_t::string: + return "string"; + case value_t::boolean: + return "boolean"; + case value_t::binary: + return "binary"; + case value_t::discarded: + return "discarded"; + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + default: + return "number"; } } @@ -24726,104 +21005,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @{ public: - /*! - @brief create a CBOR serialization of a given JSON value - - Serializes a given JSON value @a 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. - - 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. - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a CBOR value. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note 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) - - @param[in] j JSON value to serialize - @return CBOR serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in CBOR format.,to_cbor} - - @sa http://cbor.io - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - analogous deserialization - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; compact representation of floating-point numbers - since version 3.8.0 - */ + /// @brief create a CBOR serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/ static std::vector to_cbor(const basic_json& j) { std::vector result; @@ -24831,94 +21014,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } + /// @brief create a CBOR serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/ static void to_cbor(const basic_json& j, detail::output_adapter o) { binary_writer(o).write_cbor(j); } + /// @brief create a CBOR serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_cbor/ static void to_cbor(const basic_json& j, detail::output_adapter o) { binary_writer(o).write_cbor(j); } - /*! - @brief create a MessagePack serialization of a given JSON value - - Serializes a given JSON value @a 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. - - 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 - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a MessagePack value. - - @note 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 - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @param[in] j JSON value to serialize - @return MessagePack serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in MessagePack format.,to_msgpack} - - @sa http://msgpack.org - @sa see @ref from_msgpack for the analogous deserialization - @sa see @ref to_cbor(const basic_json& for the related CBOR format - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9 - */ + /// @brief create a MessagePack serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/ static std::vector to_msgpack(const basic_json& j) { std::vector result; @@ -24926,102 +21037,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } + /// @brief create a MessagePack serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/ static void to_msgpack(const basic_json& j, detail::output_adapter o) { binary_writer(o).write_msgpack(j); } + /// @brief create a MessagePack serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_msgpack/ static void to_msgpack(const basic_json& j, detail::output_adapter o) { binary_writer(o).write_msgpack(j); } - /*! - @brief create a UBJSON serialization of a given JSON value - - Serializes a given JSON value @a 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. - - 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 | `{` - - @note The mapping is **complete** in the sense that any JSON value type - can be converted to a UBJSON value. - - @note The following values can **not** be converted to a UBJSON value: - - strings with more than 9223372036854775807 bytes (theoretical) - - @note 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. - - @note Any UBJSON output created @ref to_ubjson can be successfully parsed - by @ref from_ubjson. - - @note If NaN or Infinity are stored inside a JSON number, they are - serialized properly. This behavior differs from the @ref dump() - function which serializes NaN or Infinity to `null`. - - @note The optimized formats for containers are supported: Parameter - @a use_size adds size information to the beginning of a container and - removes the closing marker. Parameter @a 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 @a use_type - parameter must only be used together with @a use_size = true. Note - that @a 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. - - @note 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. - - @param[in] j JSON value to serialize - @param[in] use_size whether to add size annotations to container types - @param[in] use_type whether to add type annotations to container types - (must be combined with @a use_size = true) - @return UBJSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in UBJSON format.,to_ubjson} - - @sa http://ubjson.org - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - analogous deserialization - @sa see @ref to_cbor(const basic_json& for the related CBOR format - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - - @since version 3.1.0 - */ + /// @brief create a UBJSON serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/ static std::vector to_ubjson(const basic_json& j, const bool use_size = false, const bool use_type = false) @@ -25031,75 +21062,24 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } + /// @brief create a UBJSON serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/ static void to_ubjson(const basic_json& j, detail::output_adapter o, const bool use_size = false, const bool use_type = false) { binary_writer(o).write_ubjson(j, use_size, use_type); } + /// @brief create a UBJSON serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_ubjson/ static void to_ubjson(const basic_json& j, detail::output_adapter o, const bool use_size = false, const bool use_type = false) { binary_writer(o).write_ubjson(j, use_size, use_type); } - - /*! - @brief Serializes the given JSON object `j` to BSON and returns a vector - containing the corresponding BSON-representation. - - 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). - - 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 - - @warning 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. - - @throw out_of_range.407 if `j.is_number_unsigned() && j.get() > 9223372036854775807` - @throw out_of_range.409 if a key in `j` contains a NULL (U+0000) - @throw type_error.317 if `!j.is_object()` - - @pre The input `j` is required to be an object: `j.is_object() == true`. - - @note Any BSON output created via @ref to_bson can be successfully parsed - by @ref from_bson. - - @param[in] j JSON value to serialize - @return BSON serialization as byte vector - - @complexity Linear in the size of the JSON value @a j. - - @liveexample{The example shows the serialization of a JSON value to a byte - vector in BSON format.,to_bson} - - @sa http://bsonspec.org/spec.html - @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the - analogous deserialization - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - related UBJSON format - @sa see @ref to_cbor(const basic_json&) for the related CBOR format - @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format - */ + /// @brief create a BSON serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_bson/ static std::vector to_bson(const basic_json& j) { std::vector result; @@ -25107,130 +21087,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief Serializes the given JSON object `j` to BSON and forwards the - corresponding BSON-representation to the given output_adapter `o`. - @param j The JSON object to convert to BSON. - @param o The output adapter that receives the binary BSON representation. - @pre The input `j` shall be an object: `j.is_object() == true` - @sa see @ref to_bson(const basic_json&) - */ + /// @brief create a BSON serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_bson/ static void to_bson(const basic_json& j, detail::output_adapter o) { binary_writer(o).write_bson(j); } - /*! - @copydoc to_bson(const basic_json&, detail::output_adapter) - */ + /// @brief create a BSON serialization of a given JSON value + /// @sa https://json.nlohmann.me/api/basic_json/to_bson/ static void to_bson(const basic_json& j, detail::output_adapter o) { binary_writer(o).write_bson(j); } - - /*! - @brief create a JSON value from an input in CBOR format - - Deserializes a given input @a i to a JSON value using the CBOR (Concise - Binary Object Representation) serialization format. - - The library maps CBOR types to JSON value types as follows: - - CBOR type | JSON value type | first byte - ---------------------- | --------------- | ---------- - Integer | number_unsigned | 0x00..0x17 - Unsigned integer | number_unsigned | 0x18 - Unsigned integer | number_unsigned | 0x19 - Unsigned integer | number_unsigned | 0x1A - Unsigned integer | number_unsigned | 0x1B - Negative integer | number_integer | 0x20..0x37 - Negative integer | number_integer | 0x38 - Negative integer | number_integer | 0x39 - Negative integer | number_integer | 0x3A - Negative integer | number_integer | 0x3B - Byte string | binary | 0x40..0x57 - Byte string | binary | 0x58 - Byte string | binary | 0x59 - Byte string | binary | 0x5A - Byte string | binary | 0x5B - UTF-8 string | string | 0x60..0x77 - UTF-8 string | string | 0x78 - UTF-8 string | string | 0x79 - UTF-8 string | string | 0x7A - UTF-8 string | string | 0x7B - UTF-8 string | string | 0x7F - array | array | 0x80..0x97 - array | array | 0x98 - array | array | 0x99 - array | array | 0x9A - array | array | 0x9B - array | array | 0x9F - map | object | 0xA0..0xB7 - map | object | 0xB8 - map | object | 0xB9 - map | object | 0xBA - map | object | 0xBB - map | object | 0xBF - False | `false` | 0xF4 - True | `true` | 0xF5 - Null | `null` | 0xF6 - Half-Precision Float | number_float | 0xF9 - Single-Precision Float | number_float | 0xFA - Double-Precision Float | number_float | 0xFB - - @warning 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 (parse_error.112): - - date/time (0xC0..0xC1) - - bignum (0xC2..0xC3) - - decimal fraction (0xC4) - - bigfloat (0xC5) - - expected conversions (0xD5..0xD7) - - simple values (0xE0..0xF3, 0xF8) - - undefined (0xF7) - - @warning 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 (parse_error.113). - - @note Any CBOR output created @ref to_cbor can be successfully parsed by - @ref from_cbor. - - @param[in] i an input in CBOR format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - @param[in] tag_handler how to treat CBOR tags (optional, error by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from CBOR were - used in the given input @a v or if the input is not valid CBOR - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in CBOR - format to a JSON value.,from_cbor} - - @sa http://cbor.io - @sa see @ref to_cbor(const basic_json&) for the analogous serialization - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the - related MessagePack format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - related UBJSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0; added @a tag_handler parameter since 3.9.0. - */ + /// @brief create a JSON value from an input in CBOR format + /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_cbor(InputType&& i, @@ -25245,9 +21117,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /*! - @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) - */ + /// @brief create a JSON value from an input in CBOR format + /// @sa https://json.nlohmann.me/api/basic_json/from_cbor/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_cbor(IteratorType first, IteratorType last, @@ -25289,92 +21160,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /*! - @brief create a JSON value from an input in MessagePack format - - Deserializes a given input @a i to a JSON value using the MessagePack - serialization format. - - 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 - - @note Any MessagePack output created @ref to_msgpack can be successfully - parsed by @ref from_msgpack. - - @param[in] i an input in MessagePack format convertible to an input - adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if unsupported features from MessagePack were - used in the given input @a i or if the input is not valid MessagePack - @throw parse_error.113 if a string was expected as map key, but not found - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - MessagePack format to a JSON value.,from_msgpack} - - @sa http://msgpack.org - @sa see @ref to_msgpack(const basic_json&) for the analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for - the related UBJSON format - @sa see @ref from_bson(InputType&&, const bool, const bool) for - the related BSON format - - @since version 2.0.9; parameter @a start_index since 2.1.1; changed to - consume input adapters, removed start_index parameter, and added - @a strict parameter since 3.0.0; added @a allow_exceptions parameter - since 3.2.0 - */ + /// @brief create a JSON value from an input in MessagePack format + /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_msgpack(InputType&& i, @@ -25388,9 +21175,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /*! - @copydoc from_msgpack(InputType&&, const bool, const bool) - */ + /// @brief create a JSON value from an input in MessagePack format + /// @sa https://json.nlohmann.me/api/basic_json/from_msgpack/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_msgpack(IteratorType first, IteratorType last, @@ -25404,7 +21190,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - template JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len)) @@ -25429,69 +21214,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - - /*! - @brief create a JSON value from an input in UBJSON format - - Deserializes a given input @a i to a JSON value using the UBJSON (Universal - Binary JSON) serialization format. - - 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` - high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H' - string | string | `S` - char | string | `C` - array | array (optimized values are supported) | `[` - object | object (optimized values are supported) | `{` - - @note The mapping is **complete** in the sense that any UBJSON value can - be converted to a JSON value. - - @param[in] i an input in UBJSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.110 if the given input ends prematurely or the end of - file was not reached when @a strict was set to true - @throw parse_error.112 if a parse error occurs - @throw parse_error.113 if a string could not be parsed successfully - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - UBJSON format to a JSON value.,from_ubjson} - - @sa http://ubjson.org - @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the - analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for - the related MessagePack format - @sa see @ref from_bson(InputType&&, const bool, const bool) for - the related BSON format - - @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0 - */ + /// @brief create a JSON value from an input in UBJSON format + /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_ubjson(InputType&& i, @@ -25505,9 +21229,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /*! - @copydoc from_ubjson(InputType&&, const bool, const bool) - */ + /// @brief create a JSON value from an input in UBJSON format + /// @sa https://json.nlohmann.me/api/basic_json/from_ubjson/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_ubjson(IteratorType first, IteratorType last, @@ -25545,67 +21268,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - - /*! - @brief Create a JSON value from an input in BSON format - - Deserializes a given input @a i to a JSON value using the BSON (Binary JSON) - serialization format. - - 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 | still unsupported - ObjectId | 0x07 | still unsupported - boolean | 0x08 | boolean - UTC Date-Time | 0x09 | still unsupported - null | 0x0A | null - Regular Expr. | 0x0B | still unsupported - DB Pointer | 0x0C | still unsupported - JavaScript Code | 0x0D | still unsupported - Symbol | 0x0E | still unsupported - JavaScript Code | 0x0F | still unsupported - int32 | 0x10 | number_integer - Timestamp | 0x11 | still unsupported - 128-bit decimal float | 0x13 | still unsupported - Max Key | 0x7F | still unsupported - Min Key | 0xFF | still unsupported - - @warning The mapping is **incomplete**. The unsupported mappings - are indicated in the table above. - - @param[in] i an input in BSON format convertible to an input adapter - @param[in] strict whether to expect the input to be consumed until EOF - (true by default) - @param[in] allow_exceptions whether to throw exceptions in case of a - parse error (optional, true by default) - - @return deserialized JSON value; in case of a parse error and - @a allow_exceptions set to `false`, the return value will be - value_t::discarded. - - @throw parse_error.114 if an unsupported BSON record type is encountered - - @complexity Linear in the size of the input @a i. - - @liveexample{The example shows the deserialization of a byte vector in - BSON format to a JSON value.,from_bson} - - @sa http://bsonspec.org/spec.html - @sa see @ref to_bson(const basic_json&) for the analogous serialization - @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the - related CBOR format - @sa see @ref from_msgpack(InputType&&, const bool, const bool) for - the related MessagePack format - @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the - related UBJSON format - */ + /// @brief create a JSON value from an input in BSON format + /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bson(InputType&& i, @@ -25619,9 +21283,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return res ? result : basic_json(value_t::discarded); } - /*! - @copydoc from_bson(InputType&&, const bool, const bool) - */ + /// @brief create a JSON value from an input in BSON format + /// @sa https://json.nlohmann.me/api/basic_json/from_bson/ template JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json from_bson(IteratorType first, IteratorType last, @@ -25667,180 +21330,36 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name JSON Pointer functions /// @{ - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. Similar to @ref operator[](const typename - object_t::key_type&), `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 an 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 an 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. - - @param[in] ptr a JSON pointer - - @return reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer} - - @since version 2.0.0 - */ + /// @brief access specified element via JSON Pointer + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ reference operator[](const json_pointer& ptr) { return ptr.get_unchecked(this); } - /*! - @brief access specified element via JSON Pointer - - Uses a JSON pointer to retrieve a reference to the respective JSON value. - No bound checking is performed. The function does not change the JSON - value; no `null` values are created. In particular, the special value - `-` yields an exception. - - @param[in] ptr JSON pointer to the desired element - - @return const reference to the element pointed to by @a ptr - - @complexity Constant. - - @throw parse_error.106 if an array index begins with '0' - @throw parse_error.109 if an array index was not a number - @throw out_of_range.402 if the array index '-' is used - @throw out_of_range.404 if the JSON pointer can not be resolved - - @liveexample{The behavior is shown in the example.,operatorjson_pointer_const} - - @since version 2.0.0 - */ + /// @brief access specified element via JSON Pointer + /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ const_reference operator[](const json_pointer& ptr) const { return ptr.get_unchecked(this); } - /*! - @brief access specified element via JSON Pointer - - Returns a reference to the element at with specified JSON pointer @a ptr, - with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer} - */ + /// @brief access specified element via JSON Pointer + /// @sa https://json.nlohmann.me/api/basic_json/at/ reference at(const json_pointer& ptr) { return ptr.get_checked(this); } - /*! - @brief access specified element via JSON Pointer - - Returns a const reference to the element at with specified JSON pointer @a - ptr, with bounds checking. - - @param[in] ptr JSON pointer to the desired element - - @return reference to the element pointed to by @a ptr - - @throw parse_error.106 if an array index in the passed JSON pointer @a ptr - begins with '0'. See example below. - - @throw parse_error.109 if an array index in the passed JSON pointer @a ptr - is not a number. See example below. - - @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr - is out of range. See example below. - - @throw out_of_range.402 if the array index '-' is used in the passed JSON - pointer @a ptr. As `at` provides checked access (and no elements are - implicitly inserted), the index '-' is always invalid. See example below. - - @throw out_of_range.403 if the JSON pointer describes a key of an object - which cannot be found. See example below. - - @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved. - See example below. - - @exceptionsafety Strong guarantee: if an exception is thrown, there are no - changes in the JSON value. - - @complexity Constant. - - @since version 2.0.0 - - @liveexample{The behavior is shown in the example.,at_json_pointer_const} - */ + /// @brief access specified element via JSON Pointer + /// @sa https://json.nlohmann.me/api/basic_json/at/ const_reference at(const json_pointer& ptr) const { return ptr.get_checked(this); } - /*! - @brief return flattened JSON value - - The function creates a JSON object whose keys are JSON pointers (see [RFC - 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all - primitive. The original JSON value can be restored using the @ref - unflatten() function. - - @return an object that maps JSON pointers to primitive values - - @note Empty objects and arrays are flattened to `null` and will not be - reconstructed correctly by the @ref unflatten() function. - - @complexity Linear in the size the JSON value. - - @liveexample{The following code shows how a JSON object is flattened to an - object whose keys consist of JSON pointers.,flatten} - - @sa see @ref unflatten() for the reverse function - - @since version 2.0.0 - */ + /// @brief return flattened JSON value + /// @sa https://json.nlohmann.me/api/basic_json/flatten/ basic_json flatten() const { basic_json result(value_t::object); @@ -25848,36 +21367,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief unflatten a previously flattened JSON value - - The function restores the arbitrary nesting of a JSON value that has been - flattened before using the @ref 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](https://tools.ietf.org/html/rfc6901)) - 3. The mapped values must be primitive JSON types. - - @return the original JSON from a flattened version - - @note Empty objects and arrays are flattened by @ref 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()`. - - @complexity Linear in the size the JSON value. - - @throw type_error.314 if value is not an object - @throw type_error.315 if object values are not primitive - - @liveexample{The following code shows how a flattened JSON object is - unflattened into the original nested JSON object.,unflatten} - - @sa see @ref flatten() for the reverse function - - @since version 2.0.0 - */ + /// @brief unflatten a previously flattened JSON value + /// @sa https://json.nlohmann.me/api/basic_json/unflatten/ basic_json unflatten() const { return json_pointer::unflatten(*this); @@ -25892,53 +21383,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name JSON Patch functions /// @{ - /*! - @brief applies a JSON patch - - [JSON Patch](http://jsonpatch.com) defines a JSON document structure for - expressing a sequence of operations to apply to a JSON) document. With - this function, a JSON Patch is applied to the current JSON value by - executing all operations from the patch. - - @param[in] json_patch JSON patch document - @return patched document - - @note 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. - - @throw parse_error.104 if the JSON patch does not consist of an array of - objects - - @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory - attributes are missing); example: `"operation add must have member path"` - - @throw out_of_range.401 if an array index is out of range. - - @throw 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"` - - @throw out_of_range.405 if JSON pointer has no parent ("add", "remove", - "move") - - @throw other_error.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. - - @liveexample{The following code shows how a JSON patch is applied to a - value.,patch} - - @sa see @ref diff -- create a JSON patch by comparing two JSON values - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) - - @since version 2.0.0 - */ + /// @brief applies a JSON patch + /// @sa https://json.nlohmann.me/api/basic_json/patch/ basic_json patch(const basic_json& json_patch) const { // make a working copy to apply the patch to @@ -26211,39 +21657,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return result; } - /*! - @brief creates a diff as a JSON patch - - Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can - be changed into the value @a target by calling @ref patch function. - - @invariant For two JSON values @a source and @a target, the following code - yields always `true`: - @code {.cpp} - source.patch(diff(source, target)) == target; - @endcode - - @note Currently, only `remove`, `add`, and `replace` operations are - generated. - - @param[in] source JSON value to compare from - @param[in] target JSON value to compare against - @param[in] path helper value to create JSON pointers - - @return a JSON patch to convert the @a source to @a target - - @complexity Linear in the lengths of @a source and @a target. - - @liveexample{The following code shows how a JSON patch is created as a - diff for two JSON values.,diff} - - @sa see @ref patch -- apply a JSON patch - @sa see @ref merge_patch -- apply a JSON Merge Patch - - @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - - @since version 2.0.0 - */ + /// @brief creates a diff as a JSON patch + /// @sa https://json.nlohmann.me/api/basic_json/diff/ JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json diff(const basic_json& source, const basic_json& target, const std::string& path = "") @@ -26281,7 +21696,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec ++i; } - // i now reached the end of at least one array + // We now reached the end of at least one array // in a second pass, traverse the remaining elements // remove my remaining elements @@ -26386,48 +21801,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @name JSON Merge Patch functions /// @{ - /*! - @brief applies a JSON Merge Patch - - The merge patch format is primarily intended for use with the HTTP PATCH - method as a means of describing a set of modifications to a target - resource's content. This function applies a merge patch to the current - JSON value. - - The function implements the following algorithm from Section 2 of - [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396): - - ``` - define MergePatch(Target, Patch): - if Patch is an Object: - if Target is not an Object: - Target = {} // Ignore the contents and set it to an empty Object - for each Name/Value pair in Patch: - if Value is null: - if Name exists in Target: - remove the Name/Value pair from Target - else: - Target[Name] = MergePatch(Target[Name], Value) - return Target - else: - return Patch - ``` - - Thereby, `Target` is the current object; that is, the patch is applied to - the current value. - - @param[in] apply_patch the patch to apply - - @complexity Linear in the lengths of @a patch. - - @liveexample{The following code shows how a JSON Merge Patch is applied to - a JSON document.,merge_patch} - - @sa see @ref patch -- apply a JSON patch - @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - - @since version 3.0.0 - */ + /// @brief applies a JSON Merge Patch + /// @sa https://json.nlohmann.me/api/basic_json/merge_patch/ void merge_patch(const basic_json& apply_patch) { if (apply_patch.is_object()) @@ -26457,50 +21832,37 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @} }; -/*! -@brief user-defined to_string function for JSON values - -This function implements a user-defined to_string for JSON objects. - -@param[in] j a JSON object -@return a std::string object -*/ - +/// @brief user-defined to_string function for JSON values +/// @sa https://json.nlohmann.me/api/basic_json/to_string/ NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j) { return j.dump(); } + } // namespace nlohmann /////////////////////// // nonmember support // /////////////////////// -// specialization of std::swap, and std::hash -namespace std +namespace std // NOLINT(cert-dcl58-cpp) { -/// hash value for JSON objects -template<> -struct hash +/// @brief hash value for JSON objects +/// @sa https://json.nlohmann.me/api/basic_json/std_hash/ +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct hash { - /*! - @brief return a hash value for a JSON object - - @since version 1.0.0 - */ - std::size_t operator()(const nlohmann::json& j) const + std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const { return nlohmann::detail::hash(j); } }; -/// specialization for std::less -/// @note: do not remove the space after '<', -/// see https://github.com/nlohmann/json/pull/679 +// specialization for std::less template<> -struct less<::nlohmann::detail::value_t> +struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679 { /*! @brief compare two value_t enum values @@ -26516,16 +21878,12 @@ struct less<::nlohmann::detail::value_t> // C++20 prohibit function specialization in the std namespace. #ifndef JSON_HAS_CPP_20 -/*! -@brief exchanges the values of two JSON objects - -@since version 1.0.0 -*/ -template<> -inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) - is_nothrow_move_constructible::value&& // NOLINT(misc-redundant-expression) - is_nothrow_move_assignable::value - ) +/// @brief exchanges the values of two JSON objects +/// @sa https://json.nlohmann.me/api/basic_json/std_swap/ +NLOHMANN_BASIC_JSON_TPL_DECLARATION +inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name) + is_nothrow_move_constructible::value&& // NOLINT(misc-redundant-expression) + is_nothrow_move_assignable::value) { j1.swap(j2); } @@ -26534,38 +21892,16 @@ inline void swap(nlohmann::json& j1, nlohmann::json& j2) noexcep } // namespace std -/*! -@brief user-defined string literal for JSON values - -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. - -@param[in] s a string representation of a JSON object -@param[in] n the length of string @a s -@return a JSON object - -@since version 1.0.0 -*/ +/// @brief user-defined string literal for JSON values +/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json/ JSON_HEDLEY_NON_NULL(1) inline nlohmann::json operator "" _json(const char* s, std::size_t n) { return nlohmann::json::parse(s, s + n); } -/*! -@brief user-defined string literal for JSON pointer - -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. - -@param[in] s a string representation of a JSON Pointer -@param[in] n the length of string @a s -@return a JSON pointer object - -@since version 2.0.0 -*/ +/// @brief user-defined string literal for JSON pointer +/// @sa https://json.nlohmann.me/api/basic_json/operator_literal_json_pointer/ JSON_HEDLEY_NON_NULL(1) inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n) { @@ -26591,6 +21927,8 @@ inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std #undef JSON_HAS_CPP_14 #undef JSON_HAS_CPP_17 #undef JSON_HAS_CPP_20 +#undef JSON_HAS_FILESYSTEM +#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION #undef NLOHMANN_BASIC_JSON_TPL #undef JSON_EXPLICIT diff --git a/module/lib/jsoncons/basic_json.hpp b/module/lib/jsoncons/basic_json.hpp index 30e63dc7..27d05bf2 100644 --- a/module/lib/jsoncons/basic_json.hpp +++ b/module/lib/jsoncons/basic_json.hpp @@ -27,7 +27,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -101,7 +102,7 @@ namespace jsoncons { template ::value && std::is_convertible::value>::type> random_access_iterator_wrapper(const random_access_iterator_wrapper& other) - : it_(other.it_), has_value_(true) + : it_(other.it_), has_value_(other.has_value_) { } @@ -229,27 +230,40 @@ namespace jsoncons { { return next += offset; } + + bool has_value() const + { + return has_value_; + } }; } // namespace detail struct sorted_policy { - using key_order = sort_key_order; + template + using object = sorted_json_object; - template - using sequence_container_type = std::vector; - - template - using key_storage = std::basic_string; + template + using array = json_array; using parse_error_handler_type = default_json_parsing; }; - struct preserve_order_policy : public sorted_policy + struct order_preserving_policy { - using key_order = preserve_key_order; + template + using object = order_preserving_json_object; + + template + using array = json_array; + + using parse_error_handler_type = default_json_parsing; }; + #if !defined(JSONCONS_NO_DEPRECATED) + using preserve_order_policy = order_preserving_policy; + #endif + template class range { @@ -355,11 +369,11 @@ namespace jsoncons { JSONCONS_DEPRECATED_MSG("Instead, use key_value_type") typedef key_value_type member_type; #endif - using array = json_array; + using array = typename ImplementationPolicy::template array; using key_value_allocator_type = typename std::allocator_traits:: template rebind_alloc; - using object = json_object; + using object = typename ImplementationPolicy::template object; using object_iterator = jsoncons::detail::random_access_iterator_wrapper; using const_object_iterator = jsoncons::detail::random_access_iterator_wrapper; @@ -374,7 +388,7 @@ namespace jsoncons { class common_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; }; @@ -382,12 +396,12 @@ namespace jsoncons { class null_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; null_storage(semantic_tag tag = semantic_tag::none) - : storage_(static_cast(storage_kind::null_value)), length_(0), tag_(tag) + : storage_kind_(static_cast(json_storage_kind::null_value)), length_(0), tag_(tag) { } }; @@ -395,12 +409,12 @@ namespace jsoncons { class empty_object_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; empty_object_storage(semantic_tag tag) - : storage_(static_cast(storage_kind::empty_object_value)), length_(0), tag_(tag) + : storage_kind_(static_cast(json_storage_kind::empty_object_value)), length_(0), tag_(tag) { } }; @@ -408,14 +422,14 @@ namespace jsoncons { class bool_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: bool val_; public: bool_storage(bool val, semantic_tag tag) - : storage_(static_cast(storage_kind::bool_value)), length_(0), tag_(tag), + : storage_kind_(static_cast(json_storage_kind::bool_value)), length_(0), tag_(tag), val_(val) { } @@ -430,7 +444,7 @@ namespace jsoncons { class int64_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -438,7 +452,7 @@ namespace jsoncons { public: int64_storage(int64_t val, semantic_tag tag = semantic_tag::none) - : storage_(static_cast(storage_kind::int64_value)), length_(0), tag_(tag), + : storage_kind_(static_cast(json_storage_kind::int64_value)), length_(0), tag_(tag), val_(val) { } @@ -452,7 +466,7 @@ namespace jsoncons { class uint64_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -460,7 +474,7 @@ namespace jsoncons { public: uint64_storage(uint64_t val, semantic_tag tag = semantic_tag::none) - : storage_(static_cast(storage_kind::uint64_value)), length_(0), tag_(tag), + : storage_kind_(static_cast(json_storage_kind::uint64_value)), length_(0), tag_(tag), val_(val) { } @@ -474,14 +488,14 @@ namespace jsoncons { class half_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: uint16_t val_; public: half_storage(uint16_t val, semantic_tag tag = semantic_tag::none) - : storage_(static_cast(storage_kind::half_value)), length_(0), tag_(tag), + : storage_kind_(static_cast(json_storage_kind::half_value)), length_(0), tag_(tag), val_(val) { } @@ -495,7 +509,7 @@ namespace jsoncons { class double_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -503,7 +517,7 @@ namespace jsoncons { public: double_storage(double val, semantic_tag tag = semantic_tag::none) - : storage_(static_cast(storage_kind::double_value)), length_(0), tag_(tag), + : storage_kind_(static_cast(json_storage_kind::double_value)), length_(0), tag_(tag), val_(val) { } @@ -517,7 +531,7 @@ namespace jsoncons { class short_string_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -527,7 +541,7 @@ namespace jsoncons { static constexpr size_t max_length = capacity - 1; short_string_storage(semantic_tag tag, const char_type* p, uint8_t length) - : storage_(static_cast(storage_kind::short_string_value)), length_(length), tag_(tag) + : storage_kind_(static_cast(json_storage_kind::short_string_value)), length_(length), tag_(tag) { JSONCONS_ASSERT(length <= max_length); std::memcpy(data_,p,length*sizeof(char_type)); @@ -535,7 +549,7 @@ namespace jsoncons { } short_string_storage(const short_string_storage& val) - : storage_(val.storage_), length_(val.length_), tag_(val.tag_) + : storage_kind_(val.storage_kind_), length_(val.length_), tag_(val.tag_) { std::memcpy(data_,val.data_,val.length_*sizeof(char_type)); data_[length_] = 0; @@ -563,7 +577,7 @@ namespace jsoncons { class long_string_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -571,26 +585,26 @@ namespace jsoncons { public: long_string_storage(semantic_tag tag, const char_type* data, std::size_t length, const Allocator& a) - : storage_(static_cast(storage_kind::long_string_value)), length_(0), tag_(tag), + : storage_kind_(static_cast(json_storage_kind::long_string_value)), length_(0), tag_(tag), s_(data, length, a) { } long_string_storage(const long_string_storage& val) - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), s_(val.s_) { } long_string_storage(long_string_storage&& val) noexcept - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), s_(nullptr) { swap(val); } long_string_storage(const long_string_storage& val, const Allocator& a) - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), s_(val.s_, a) { } @@ -633,7 +647,7 @@ namespace jsoncons { class byte_string_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -641,26 +655,26 @@ namespace jsoncons { public: byte_string_storage(semantic_tag tag, const uint8_t* data, std::size_t length, uint64_t ext_tag, const Allocator& alloc) - : storage_(static_cast(storage_kind::byte_string_value)), length_(0), tag_(tag), + : storage_kind_(static_cast(json_storage_kind::byte_string_value)), length_(0), tag_(tag), s_(data, length, ext_tag, alloc) { } byte_string_storage(const byte_string_storage& val) - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), s_(val.s_) { } byte_string_storage(byte_string_storage&& val) noexcept - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), s_(nullptr) { swap(val); } byte_string_storage(const byte_string_storage& val, const Allocator& a) - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), s_(val.s_, a) { } @@ -699,7 +713,7 @@ namespace jsoncons { class array_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -731,32 +745,38 @@ namespace jsoncons { } public: array_storage(const array& val, semantic_tag tag) - : storage_(static_cast(storage_kind::array_value)), length_(0), tag_(tag) + : storage_kind_(static_cast(json_storage_kind::array_value)), length_(0), tag_(tag) { create(val.get_allocator(), val); } + array_storage(array&& val, semantic_tag tag) + : storage_kind_(static_cast(json_storage_kind::array_value)), length_(0), tag_(tag) + { + create(val.get_allocator(), std::forward(val)); + } + array_storage(const array& val, semantic_tag tag, const Allocator& a) - : storage_(val.storage_), length_(0), tag_(tag) + : storage_kind_(val.storage_kind_), length_(0), tag_(tag) { create(array_allocator(a), val, a); } array_storage(const array_storage& val) - : storage_(val.storage_), length_(0), tag_(val.tag_) + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_) { create(val.ptr_->get_allocator(), *(val.ptr_)); } array_storage(array_storage&& val) noexcept - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), ptr_(nullptr) { std::swap(val.ptr_, ptr_); } array_storage(const array_storage& val, const Allocator& a) - : storage_(val.storage_), length_(0), tag_(val.tag_) + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_) { create(array_allocator(a), *(val.ptr_), a); } @@ -793,7 +813,7 @@ namespace jsoncons { class object_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: @@ -818,32 +838,38 @@ namespace jsoncons { } public: explicit object_storage(const object& val, semantic_tag tag) - : storage_(static_cast(storage_kind::object_value)), length_(0), tag_(tag) + : storage_kind_(static_cast(json_storage_kind::object_value)), length_(0), tag_(tag) { create(val.get_allocator(), val); } + explicit object_storage(object&& val, semantic_tag tag) + : storage_kind_(static_cast(json_storage_kind::object_value)), length_(0), tag_(tag) + { + create(val.get_allocator(), std::forward(val)); + } + explicit object_storage(const object& val, semantic_tag tag, const Allocator& a) - : storage_(val.storage_), length_(0), tag_(tag) + : storage_kind_(val.storage_kind_), length_(0), tag_(tag) { create(object_allocator(a), val, a); } explicit object_storage(const object_storage& val) - : storage_(val.storage_), length_(0), tag_(val.tag_) + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_) { create(val.ptr_->get_allocator(), *(val.ptr_)); } explicit object_storage(object_storage&& val) noexcept - : storage_(val.storage_), length_(0), tag_(val.tag_), + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_), ptr_(nullptr) { std::swap(val.ptr_,ptr_); } explicit object_storage(const object_storage& val, const Allocator& a) - : storage_(val.storage_), length_(0), tag_(val.tag_) + : storage_kind_(val.storage_kind_), length_(0), tag_(val.tag_) { create(object_allocator(a), *(val.ptr_), a); } @@ -888,14 +914,14 @@ namespace jsoncons { class json_const_pointer_storage final { public: - uint8_t storage_:4; + uint8_t storage_kind_:4; uint8_t length_:4; semantic_tag tag_; private: const basic_json* p_; public: json_const_pointer_storage(const basic_json* p) - : storage_(static_cast(storage_kind::json_const_pointer)), length_(0), tag_(p->tag()), + : storage_kind_(static_cast(json_storage_kind::json_const_pointer)), length_(0), tag_(p->tag()), p_(p) { } @@ -1013,9 +1039,9 @@ namespace jsoncons { return evaluate().size(); } - storage_kind storage() const + json_storage_kind storage_kind() const { - return evaluate().storage(); + return evaluate().storage_kind(); } semantic_tag tag() const @@ -1359,15 +1385,15 @@ namespace jsoncons { } // Remove all elements from an array or object - void erase(const_object_iterator pos) + object_iterator erase(const_object_iterator pos) { - evaluate().erase(pos); + return evaluate().erase(pos); } // Remove a range of elements from an object - void erase(const_object_iterator first, const_object_iterator last) + object_iterator erase(const_object_iterator first, const_object_iterator last) { - evaluate().erase(first, last); + return evaluate().erase(first, last); } // Remove a range of elements from an object @@ -1376,15 +1402,15 @@ namespace jsoncons { evaluate().erase(name); } - void erase(const_array_iterator pos) + array_iterator erase(const_array_iterator pos) { - evaluate().erase(pos); + return evaluate().erase(pos); } // Removes the element at pos - void erase(const_array_iterator first, const_array_iterator last) + array_iterator erase(const_array_iterator first, const_array_iterator last) { - evaluate().erase(first, last); + return evaluate().erase(first, last); } // Remove a range of elements from an array @@ -1898,18 +1924,18 @@ namespace jsoncons { void Destroy_() { - switch (storage()) + switch (storage_kind()) { - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: destroy_var(); break; - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: destroy_var(); break; - case storage_kind::array_value: + case json_storage_kind::array_value: destroy_var(); break; - case storage_kind::object_value: + case json_storage_kind::object_value: destroy_var(); break; default: @@ -2087,21 +2113,21 @@ namespace jsoncons { template void swap_a(basic_json& other) { - switch (other.storage()) - { - case storage_kind::null_value : swap_a_b(other); break; - case storage_kind::empty_object_value : swap_a_b(other); break; - case storage_kind::bool_value : swap_a_b(other); break; - case storage_kind::int64_value : swap_a_b(other); break; - case storage_kind::uint64_value : swap_a_b(other); break; - case storage_kind::half_value : swap_a_b(other); break; - case storage_kind::double_value : swap_a_b(other); break; - case storage_kind::short_string_value : swap_a_b(other); break; - case storage_kind::long_string_value : swap_a_b(other); break; - case storage_kind::byte_string_value : swap_a_b(other); break; - case storage_kind::array_value : swap_a_b(other); break; - case storage_kind::object_value : swap_a_b(other); break; - case storage_kind::json_const_pointer : swap_a_b(other); break; + switch (other.storage_kind()) + { + case json_storage_kind::null_value : swap_a_b(other); break; + case json_storage_kind::empty_object_value : swap_a_b(other); break; + case json_storage_kind::bool_value : swap_a_b(other); break; + case json_storage_kind::int64_value : swap_a_b(other); break; + case json_storage_kind::uint64_value : swap_a_b(other); break; + case json_storage_kind::half_value : swap_a_b(other); break; + case json_storage_kind::double_value : swap_a_b(other); break; + case json_storage_kind::short_string_value : swap_a_b(other); break; + case json_storage_kind::long_string_value : swap_a_b(other); break; + case json_storage_kind::byte_string_value : swap_a_b(other); break; + case json_storage_kind::array_value : swap_a_b(other); break; + case json_storage_kind::object_value : swap_a_b(other); break; + case json_storage_kind::json_const_pointer : swap_a_b(other); break; default: JSONCONS_UNREACHABLE(); break; @@ -2110,45 +2136,45 @@ namespace jsoncons { void Init_(const basic_json& val) { - switch (val.storage()) + switch (val.storage_kind()) { - case storage_kind::null_value: + case json_storage_kind::null_value: construct(val.cast()); break; - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: construct(val.cast()); break; - case storage_kind::bool_value: + case json_storage_kind::bool_value: construct(val.cast()); break; - case storage_kind::int64_value: + case json_storage_kind::int64_value: construct(val.cast()); break; - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: construct(val.cast()); break; - case storage_kind::half_value: + case json_storage_kind::half_value: construct(val.cast()); break; - case storage_kind::double_value: + case json_storage_kind::double_value: construct(val.cast()); break; - case storage_kind::short_string_value: + case json_storage_kind::short_string_value: construct(val.cast()); break; - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: construct(val.cast()); break; - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: construct(val.cast()); break; - case storage_kind::object_value: + case json_storage_kind::object_value: construct(val.cast()); break; - case storage_kind::array_value: + case json_storage_kind::array_value: construct(val.cast()); break; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: construct(val.cast()); break; default: @@ -2158,29 +2184,29 @@ namespace jsoncons { void Init_(const basic_json& val, const Allocator& a) { - switch (val.storage()) - { - case storage_kind::null_value: - case storage_kind::empty_object_value: - case storage_kind::bool_value: - case storage_kind::int64_value: - case storage_kind::uint64_value: - case storage_kind::half_value: - case storage_kind::double_value: - case storage_kind::short_string_value: - case storage_kind::json_const_pointer: + switch (val.storage_kind()) + { + case json_storage_kind::null_value: + case json_storage_kind::empty_object_value: + case json_storage_kind::bool_value: + case json_storage_kind::int64_value: + case json_storage_kind::uint64_value: + case json_storage_kind::half_value: + case json_storage_kind::double_value: + case json_storage_kind::short_string_value: + case json_storage_kind::json_const_pointer: Init_(val); break; - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: construct(val.cast(),a); break; - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: construct(val.cast(),a); break; - case storage_kind::array_value: + case json_storage_kind::array_value: construct(val.cast(),a); break; - case storage_kind::object_value: + case json_storage_kind::object_value: construct(val.cast(),a); break; default: @@ -2190,23 +2216,23 @@ namespace jsoncons { void Init_rv_(basic_json&& val) noexcept { - switch (val.storage()) - { - case storage_kind::null_value: - case storage_kind::empty_object_value: - case storage_kind::half_value: - case storage_kind::double_value: - case storage_kind::int64_value: - case storage_kind::uint64_value: - case storage_kind::bool_value: - case storage_kind::short_string_value: - case storage_kind::json_const_pointer: + switch (val.storage_kind()) + { + case json_storage_kind::null_value: + case json_storage_kind::empty_object_value: + case json_storage_kind::half_value: + case json_storage_kind::double_value: + case json_storage_kind::int64_value: + case json_storage_kind::uint64_value: + case json_storage_kind::bool_value: + case json_storage_kind::short_string_value: + case json_storage_kind::json_const_pointer: Init_(val); break; - case storage_kind::long_string_value: - case storage_kind::byte_string_value: - case storage_kind::array_value: - case storage_kind::object_value: + case json_storage_kind::long_string_value: + case json_storage_kind::byte_string_value: + case json_storage_kind::array_value: + case json_storage_kind::object_value: { construct(); swap(val); @@ -2225,20 +2251,20 @@ namespace jsoncons { void Init_rv_(basic_json&& val, const Allocator& a, std::false_type) noexcept { - switch (val.storage()) - { - case storage_kind::null_value: - case storage_kind::empty_object_value: - case storage_kind::half_value: - case storage_kind::double_value: - case storage_kind::int64_value: - case storage_kind::uint64_value: - case storage_kind::bool_value: - case storage_kind::short_string_value: - case storage_kind::json_const_pointer: + switch (val.storage_kind()) + { + case json_storage_kind::null_value: + case json_storage_kind::empty_object_value: + case json_storage_kind::half_value: + case json_storage_kind::double_value: + case json_storage_kind::int64_value: + case json_storage_kind::uint64_value: + case json_storage_kind::bool_value: + case json_storage_kind::short_string_value: + case json_storage_kind::json_const_pointer: Init_(std::forward(val)); break; - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: { if (a == val.cast().get_allocator()) { @@ -2250,7 +2276,7 @@ namespace jsoncons { } break; } - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: { if (a == val.cast().get_allocator()) { @@ -2262,7 +2288,7 @@ namespace jsoncons { } break; } - case storage_kind::object_value: + case json_storage_kind::object_value: { if (a == val.cast().get_allocator()) { @@ -2274,7 +2300,7 @@ namespace jsoncons { } break; } - case storage_kind::array_value: + case json_storage_kind::array_value: { if (a == val.cast().get_allocator()) { @@ -2337,42 +2363,42 @@ namespace jsoncons { return *this; } - storage_kind storage() const + json_storage_kind storage_kind() const { - // It is legal to access 'common_stor_.storage_' even though - // common_stor_ is not the active member of the union because 'storage_' + // It is legal to access 'common_stor_.storage_kind_' even though + // common_stor_ is not the active member of the union because 'storage_kind_' // is a part of the common initial sequence of all union members // as defined in 11.4-25 of the Standard. - return static_cast(common_stor_.storage_); + return static_cast(common_stor_.storage_kind_); } json_type type() const { - switch(storage()) + switch(storage_kind()) { - case storage_kind::null_value: + case json_storage_kind::null_value: return json_type::null_value; - case storage_kind::bool_value: + case json_storage_kind::bool_value: return json_type::bool_value; - case storage_kind::int64_value: + case json_storage_kind::int64_value: return json_type::int64_value; - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return json_type::uint64_value; - case storage_kind::half_value: + case json_storage_kind::half_value: return json_type::half_value; - case storage_kind::double_value: + case json_storage_kind::double_value: return json_type::double_value; - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: return json_type::string_value; - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: return json_type::byte_string_value; - case storage_kind::array_value: + case json_storage_kind::array_value: return json_type::array_value; - case storage_kind::empty_object_value: - case storage_kind::object_value: + case json_storage_kind::empty_object_value: + case json_storage_kind::object_value: return json_type::object_value; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->type(); default: JSONCONS_UNREACHABLE(); @@ -2386,9 +2412,9 @@ namespace jsoncons { // common_stor_ is not the active member of the union because 'tag_' // is a part of the common initial sequence of all union members // as defined in 11.4-25 of the Standard. - switch(storage()) + switch(storage_kind()) { - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->tag(); default: return common_stor_.tag_; @@ -2397,15 +2423,15 @@ namespace jsoncons { std::size_t size() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return cast().value().size(); - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return 0; - case storage_kind::object_value: + case json_storage_kind::object_value: return cast().value().size(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->size(); default: return 0; @@ -2414,13 +2440,13 @@ namespace jsoncons { string_view_type as_string_view() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: + case json_storage_kind::short_string_value: return string_view_type(cast().data(),cast().length()); - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: return string_view_type(cast().data(),cast().length()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->as_string_view(); default: JSONCONS_THROW(json_runtime_error("Not a string")); @@ -2434,10 +2460,10 @@ namespace jsoncons { converter convert; std::error_code ec; - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: { byte_string_type v = convert.from(as_string_view(),tag(),ec); if (ec) @@ -2446,9 +2472,9 @@ namespace jsoncons { } return v; } - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: return basic_byte_string(cast().data(),cast().length()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->as_byte_string(); default: JSONCONS_THROW(json_runtime_error("Not a byte string")); @@ -2457,11 +2483,11 @@ namespace jsoncons { byte_string_view as_byte_string_view() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: return byte_string_view(cast().data(),cast().length()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->as_byte_string_view(); default: JSONCONS_THROW(json_runtime_error("Not a byte string")); @@ -2474,179 +2500,179 @@ namespace jsoncons { { return 0; } - switch (storage()) + switch (storage_kind()) { - case storage_kind::json_const_pointer: - switch (rhs.storage()) + case json_storage_kind::json_const_pointer: + switch (rhs.storage_kind()) { - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return (cast().value())->compare(*(rhs.cast().value())); default: return (cast().value())->compare(rhs); } break; - case storage_kind::null_value: - return static_cast(storage()) - static_cast((int)rhs.storage()); - case storage_kind::empty_object_value: - switch (rhs.storage()) + case json_storage_kind::null_value: + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); + case json_storage_kind::empty_object_value: + switch (rhs.storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return 0; - case storage_kind::object_value: + case json_storage_kind::object_value: return rhs.empty() ? 0 : -1; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::bool_value: - switch (rhs.storage()) + case json_storage_kind::bool_value: + switch (rhs.storage_kind()) { - case storage_kind::bool_value: + case json_storage_kind::bool_value: return static_cast(cast().value()) - static_cast(rhs.cast().value()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::int64_value: - switch (rhs.storage()) + case json_storage_kind::int64_value: + switch (rhs.storage_kind()) { - case storage_kind::int64_value: + case json_storage_kind::int64_value: { if (cast().value() == rhs.cast().value()) return 0; return cast().value() < rhs.cast().value() ? -1 : 1; } - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: if (cast().value() < 0) return -1; else if (static_cast(cast().value()) == rhs.cast().value()) return 0; else return static_cast(cast().value()) < rhs.cast().value() ? -1 : 1; - case storage_kind::double_value: + case json_storage_kind::double_value: { double r = static_cast(cast().value()) - rhs.cast().value(); return r == 0.0 ? 0 : (r < 0.0 ? -1 : 1); } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::uint64_value: - switch (rhs.storage()) + case json_storage_kind::uint64_value: + switch (rhs.storage_kind()) { - case storage_kind::int64_value: + case json_storage_kind::int64_value: if (rhs.cast().value() < 0) return 1; else if (cast().value() == static_cast(rhs.cast().value())) return 0; else return cast().value() < static_cast(rhs.cast().value()) ? -1 : 1; - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: if (cast().value() == static_cast(rhs.cast().value())) return 0; else return cast().value() < static_cast(rhs.cast().value()) ? -1 : 1; - case storage_kind::double_value: + case json_storage_kind::double_value: { auto r = static_cast(cast().value()) - rhs.cast().value(); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::double_value: - switch (rhs.storage()) + case json_storage_kind::double_value: + switch (rhs.storage_kind()) { - case storage_kind::int64_value: + case json_storage_kind::int64_value: { auto r = cast().value() - static_cast(rhs.cast().value()); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: { auto r = cast().value() - static_cast(rhs.cast().value()); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } - case storage_kind::double_value: + case json_storage_kind::double_value: { auto r = cast().value() - rhs.cast().value(); return r == 0 ? 0 : (r < 0.0 ? -1 : 1); } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::short_string_value: - case storage_kind::long_string_value: - switch (rhs.storage()) + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: + switch (rhs.storage_kind()) { - case storage_kind::short_string_value: + case json_storage_kind::short_string_value: return as_string_view().compare(rhs.as_string_view()); - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: return as_string_view().compare(rhs.as_string_view()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::byte_string_value: - switch (rhs.storage()) + case json_storage_kind::byte_string_value: + switch (rhs.storage_kind()) { - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: { return as_byte_string_view().compare(rhs.as_byte_string_view()); } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::array_value: - switch (rhs.storage()) + case json_storage_kind::array_value: + switch (rhs.storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: { if (cast().value() == rhs.cast().value()) return 0; else return cast().value() < rhs.cast().value() ? -1 : 1; } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; - case storage_kind::object_value: - switch (rhs.storage()) + case json_storage_kind::object_value: + switch (rhs.storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return empty() ? 0 : 1; - case storage_kind::object_value: + case json_storage_kind::object_value: { if (cast().value() == rhs.cast().value()) return 0; else return cast().value() < rhs.cast().value() ? -1 : 1; } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return compare(*(rhs.cast().value())); default: - return static_cast(storage()) - static_cast((int)rhs.storage()); + return static_cast(storage_kind()) - static_cast((int)rhs.storage_kind()); } break; default: @@ -2662,21 +2688,21 @@ namespace jsoncons { return; } - switch (storage()) - { - case storage_kind::null_value: swap_a(other); break; - case storage_kind::empty_object_value : swap_a(other); break; - case storage_kind::bool_value: swap_a(other); break; - case storage_kind::int64_value: swap_a(other); break; - case storage_kind::uint64_value: swap_a(other); break; - case storage_kind::half_value: swap_a(other); break; - case storage_kind::double_value: swap_a(other); break; - case storage_kind::short_string_value: swap_a(other); break; - case storage_kind::long_string_value: swap_a(other); break; - case storage_kind::byte_string_value: swap_a(other); break; - case storage_kind::array_value: swap_a(other); break; - case storage_kind::object_value: swap_a(other); break; - case storage_kind::json_const_pointer: swap_a(other); break; + switch (storage_kind()) + { + case json_storage_kind::null_value: swap_a(other); break; + case json_storage_kind::empty_object_value : swap_a(other); break; + case json_storage_kind::bool_value: swap_a(other); break; + case json_storage_kind::int64_value: swap_a(other); break; + case json_storage_kind::uint64_value: swap_a(other); break; + case json_storage_kind::half_value: swap_a(other); break; + case json_storage_kind::double_value: swap_a(other); break; + case json_storage_kind::short_string_value: swap_a(other); break; + case json_storage_kind::long_string_value: swap_a(other); break; + case json_storage_kind::byte_string_value: swap_a(other); break; + case json_storage_kind::array_value: swap_a(other); break; + case json_storage_kind::object_value: swap_a(other); break; + case json_storage_kind::json_const_pointer: swap_a(other); break; default: JSONCONS_UNREACHABLE(); break; @@ -3151,12 +3177,12 @@ namespace jsoncons { proxy_type operator[](const string_view_type& name) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: return proxy_type(*this, name); break; default: @@ -3433,11 +3459,11 @@ namespace jsoncons { bool is_null() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::null_value: + case json_storage_kind::null_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_null(); default: return false; @@ -3446,21 +3472,21 @@ namespace jsoncons { allocator_type get_allocator() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: { return cast().get_allocator(); } - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: { return cast().get_allocator(); } - case storage_kind::array_value: + case json_storage_kind::array_value: { return cast().get_allocator(); } - case storage_kind::object_value: + case json_storage_kind::object_value: { return cast().get_allocator(); } @@ -3471,13 +3497,13 @@ namespace jsoncons { uint64_t ext_tag() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: { return cast().ext_tag(); } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->ext_tag(); default: return 0; @@ -3486,14 +3512,14 @@ namespace jsoncons { bool contains(const string_view_type& key) const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(key); return it != object_value().end(); } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->contains(key); default: return false; @@ -3502,9 +3528,9 @@ namespace jsoncons { std::size_t count(const string_view_type& key) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(key); if (it == object_value().end()) @@ -3519,7 +3545,7 @@ namespace jsoncons { } return count; } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->count(key); default: return 0; @@ -3534,12 +3560,12 @@ namespace jsoncons { bool is_string() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_string(); default: return false; @@ -3553,11 +3579,11 @@ namespace jsoncons { bool is_byte_string() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_byte_string(); default: return false; @@ -3571,15 +3597,15 @@ namespace jsoncons { bool is_bignum() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: return jsoncons::detail::is_base10(as_string_view().data(), as_string_view().length()); - case storage_kind::int64_value: - case storage_kind::uint64_value: + case json_storage_kind::int64_value: + case json_storage_kind::uint64_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_bignum(); default: return false; @@ -3588,11 +3614,11 @@ namespace jsoncons { bool is_bool() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::bool_value: + case json_storage_kind::bool_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_bool(); default: return false; @@ -3601,12 +3627,12 @@ namespace jsoncons { bool is_object() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: - case storage_kind::object_value: + case json_storage_kind::empty_object_value: + case json_storage_kind::object_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_object(); default: return false; @@ -3615,11 +3641,11 @@ namespace jsoncons { bool is_array() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_array(); default: return false; @@ -3628,13 +3654,13 @@ namespace jsoncons { bool is_int64() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::int64_value: + case json_storage_kind::int64_value: return true; - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return as_integer() <= static_cast((std::numeric_limits::max)()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_int64(); default: return false; @@ -3643,13 +3669,13 @@ namespace jsoncons { bool is_uint64() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return true; - case storage_kind::int64_value: + case json_storage_kind::int64_value: return as_integer() >= 0; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_uint64(); default: return false; @@ -3658,11 +3684,11 @@ namespace jsoncons { bool is_half() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::half_value: + case json_storage_kind::half_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_half(); default: return false; @@ -3671,11 +3697,11 @@ namespace jsoncons { bool is_double() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::double_value: + case json_storage_kind::double_value: return true; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_double(); default: return false; @@ -3684,19 +3710,19 @@ namespace jsoncons { bool is_number() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::int64_value: - case storage_kind::uint64_value: - case storage_kind::half_value: - case storage_kind::double_value: + case json_storage_kind::int64_value: + case json_storage_kind::uint64_value: + case json_storage_kind::half_value: + case json_storage_kind::double_value: return true; - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: return tag() == semantic_tag::bigint || tag() == semantic_tag::bigdec || tag() == semantic_tag::bigfloat; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->is_number(); default: return false; @@ -3705,22 +3731,22 @@ namespace jsoncons { bool empty() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: return cast().length() == 0; break; - case storage_kind::short_string_value: + case json_storage_kind::short_string_value: return cast().length() == 0; - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: return cast().length() == 0; - case storage_kind::array_value: + case json_storage_kind::array_value: return array_value().empty(); - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return true; - case storage_kind::object_value: + case json_storage_kind::object_value: return object_value().empty(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->empty(); default: return false; @@ -3729,13 +3755,13 @@ namespace jsoncons { std::size_t capacity() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return array_value().capacity(); - case storage_kind::object_value: + case json_storage_kind::object_value: return object_value().capacity(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->capacity(); default: return 0; @@ -3755,25 +3781,25 @@ namespace jsoncons { void create_object_implicitly(std::true_type) { - *this = basic_json(object(Allocator()), tag()); + *this = basic_json(json_object_arg, tag()); } void reserve(std::size_t n) { if (n > 0) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: array_value().reserve(n); break; - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: { create_object_implicitly(); object_value().reserve(n); } break; - case storage_kind::object_value: + case json_storage_kind::object_value: { object_value().reserve(n); } @@ -3786,9 +3812,9 @@ namespace jsoncons { void resize(std::size_t n) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: array_value().resize(n); break; default: @@ -3799,9 +3825,9 @@ namespace jsoncons { template void resize(std::size_t n, T val) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: array_value().resize(n, val); break; default: @@ -3825,10 +3851,10 @@ namespace jsoncons { { converter convert; std::error_code ec; - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: { switch (tag()) { @@ -3856,9 +3882,9 @@ namespace jsoncons { } break; } - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: return T(as_byte_string_view().begin(), as_byte_string_view().end()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->template as(byte_string_arg, hint); default: JSONCONS_THROW(json_runtime_error("Not a byte string")); @@ -3867,15 +3893,15 @@ namespace jsoncons { bool as_bool() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::bool_value: + case json_storage_kind::bool_value: return cast().value(); - case storage_kind::int64_value: + case json_storage_kind::int64_value: return cast().value() != 0; - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return cast().value() != 0; - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->as_bool(); default: JSONCONS_THROW(json_runtime_error("Not a bool")); @@ -3885,10 +3911,10 @@ namespace jsoncons { template IntegerType as_integer() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: { IntegerType val; auto result = jsoncons::detail::to_integer(as_string_view().data(), as_string_view().length(), val); @@ -3898,17 +3924,17 @@ namespace jsoncons { } return val; } - case storage_kind::half_value: + case json_storage_kind::half_value: return static_cast(cast().value()); - case storage_kind::double_value: + case json_storage_kind::double_value: return static_cast(cast().value()); - case storage_kind::int64_value: + case json_storage_kind::int64_value: return static_cast(cast().value()); - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return static_cast(cast().value()); - case storage_kind::bool_value: + case json_storage_kind::bool_value: return static_cast(cast().value() ? 1 : 0); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->template as_integer(); default: JSONCONS_THROW(json_runtime_error("Not an integer")); @@ -3919,13 +3945,13 @@ namespace jsoncons { typename std::enable_if::value && sizeof(IntegerType) <= sizeof(int64_t),bool>::type is_integer() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::int64_value: + case json_storage_kind::int64_value: return (as_integer() >= (type_traits::integer_limits::lowest)()) && (as_integer() <= (type_traits::integer_limits::max)()); - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return as_integer() <= static_cast((type_traits::integer_limits::max)()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->template is_integer(); default: return false; @@ -3936,20 +3962,20 @@ namespace jsoncons { typename std::enable_if::value && sizeof(int64_t) < sizeof(IntegerType),bool>::type is_integer() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: { IntegerType val; auto result = jsoncons::detail::to_integer(as_string_view().data(), as_string_view().length(), val); return result ? true : false; } - case storage_kind::int64_value: + case json_storage_kind::int64_value: return (as_integer() >= (type_traits::integer_limits::lowest)()) && (as_integer() <= (type_traits::integer_limits::max)()); - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return as_integer() <= static_cast((type_traits::integer_limits::max)()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->template is_integer(); default: return false; @@ -3960,13 +3986,13 @@ namespace jsoncons { typename std::enable_if::value && sizeof(IntegerType) <= sizeof(int64_t),bool>::type is_integer() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::int64_value: + case json_storage_kind::int64_value: return as_integer() >= 0 && static_cast(as_integer()) <= (type_traits::integer_limits::max)(); - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return as_integer() <= (type_traits::integer_limits::max)(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->template is_integer(); default: return false; @@ -3977,20 +4003,20 @@ namespace jsoncons { typename std::enable_if::value && sizeof(int64_t) < sizeof(IntegerType),bool>::type is_integer() const noexcept { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: { IntegerType val; auto result = jsoncons::detail::to_integer(as_string_view().data(), as_string_view().length(), val); return result ? true : false; } - case storage_kind::int64_value: + case json_storage_kind::int64_value: return as_integer() >= 0 && static_cast(as_integer()) <= (type_traits::integer_limits::max)(); - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return as_integer() <= (type_traits::integer_limits::max)(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->template is_integer(); default: return false; @@ -3999,24 +4025,24 @@ namespace jsoncons { double as_double() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: { jsoncons::detail::to_double_t to_double; // to_double() throws std::invalid_argument if conversion fails return to_double(as_cstring(), as_string_view().length()); } - case storage_kind::half_value: + case json_storage_kind::half_value: return binary::decode_half(cast().value()); - case storage_kind::double_value: + case json_storage_kind::double_value: return cast().value(); - case storage_kind::int64_value: + case json_storage_kind::int64_value: return static_cast(cast().value()); - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: return static_cast(cast().value()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->as_double(); default: JSONCONS_THROW(json_runtime_error("Not a double")); @@ -4036,14 +4062,14 @@ namespace jsoncons { converter convert; std::error_code ec; - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: { return string_type(as_string_view().data(),as_string_view().length(),alloc); } - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: { auto s = convert.from(as_byte_string_view(), tag(), alloc, ec); if (ec) @@ -4052,7 +4078,7 @@ namespace jsoncons { } return s; } - case storage_kind::array_value: + case json_storage_kind::array_value: { string_type s(alloc); { @@ -4061,7 +4087,7 @@ namespace jsoncons { } return s; } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->as_string(alloc); default: { @@ -4075,13 +4101,13 @@ namespace jsoncons { const char_type* as_cstring() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: + case json_storage_kind::short_string_value: return cast().c_str(); - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: return cast().c_str(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->as_cstring(); default: JSONCONS_THROW(json_runtime_error("Not a cstring")); @@ -4090,11 +4116,11 @@ namespace jsoncons { basic_json& at(const string_view_type& name) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: JSONCONS_THROW(key_not_found(name.data(),name.length())); - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(name); if (it == object_value().end()) @@ -4112,11 +4138,11 @@ namespace jsoncons { const basic_json& at(const string_view_type& key) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: JSONCONS_THROW(key_not_found(key.data(),key.length())); - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(key); if (it == object_value().end()) @@ -4125,7 +4151,7 @@ namespace jsoncons { } return it->value(); } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->at(key); default: { @@ -4136,15 +4162,15 @@ namespace jsoncons { basic_json& at(std::size_t i) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: if (i >= array_value().size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return array_value().operator[](i); - case storage_kind::object_value: + case json_storage_kind::object_value: return object_value().at(i); default: JSONCONS_THROW(json_runtime_error("Index on non-array value not supported")); @@ -4153,17 +4179,17 @@ namespace jsoncons { const basic_json& at(std::size_t i) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: if (i >= array_value().size()) { JSONCONS_THROW(json_runtime_error("Invalid array subscript")); } return array_value().operator[](i); - case storage_kind::object_value: + case json_storage_kind::object_value: return object_value().at(i); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->at(i); default: JSONCONS_THROW(json_runtime_error("Index on non-array value not supported")); @@ -4172,11 +4198,11 @@ namespace jsoncons { object_iterator find(const string_view_type& name) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return object_range().end(); - case storage_kind::object_value: + case json_storage_kind::object_value: return object_iterator(object_value().find(name)); default: { @@ -4187,13 +4213,13 @@ namespace jsoncons { const_object_iterator find(const string_view_type& key) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return object_range().end(); - case storage_kind::object_value: + case json_storage_kind::object_value: return const_object_iterator(object_value().find(key)); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->find(key); default: { @@ -4204,14 +4230,14 @@ namespace jsoncons { const basic_json& at_or_null(const string_view_type& key) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::null_value: - case storage_kind::empty_object_value: + case json_storage_kind::null_value: + case json_storage_kind::empty_object_value: { return null(); } - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(key); if (it != object_value().end()) @@ -4223,7 +4249,7 @@ namespace jsoncons { return null(); } } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->at_or_null(key); default: { @@ -4239,14 +4265,14 @@ namespace jsoncons { "get_value_or: T must be copy constructible"); static_assert(std::is_convertible::value, "get_value_or: U must be convertible to T"); - switch (storage()) + switch (storage_kind()) { - case storage_kind::null_value: - case storage_kind::empty_object_value: + case json_storage_kind::null_value: + case json_storage_kind::empty_object_value: { return static_cast(std::forward(default_value)); } - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(key); if (it != object_value().end()) @@ -4258,7 +4284,7 @@ namespace jsoncons { return static_cast(std::forward(default_value)); } } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->template get_value_or(key,std::forward(default_value)); default: { @@ -4271,12 +4297,12 @@ namespace jsoncons { void shrink_to_fit() { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: array_value().shrink_to_fit(); break; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().shrink_to_fit(); break; default: @@ -4286,12 +4312,12 @@ namespace jsoncons { void clear() { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: array_value().clear(); break; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().clear(); break; default: @@ -4299,56 +4325,51 @@ namespace jsoncons { } } - void erase(const_object_iterator pos) + object_iterator erase(const_object_iterator pos) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: - break; - case storage_kind::object_value: - object_value().erase(pos); - break; + case json_storage_kind::empty_object_value: + return object_range().end(); + case json_storage_kind::object_value: + return object_iterator(object_value().erase(pos)); default: JSONCONS_THROW(json_runtime_error("Not an object")); break; } } - void erase(const_object_iterator first, const_object_iterator last) + object_iterator erase(const_object_iterator first, const_object_iterator last) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: - break; - case storage_kind::object_value: - object_value().erase(first, last); - break; + case json_storage_kind::empty_object_value: + return object_range().end(); + case json_storage_kind::object_value: + return object_iterator(object_value().erase(first, last)); default: JSONCONS_THROW(json_runtime_error("Not an object")); break; } } - void erase(const_array_iterator pos) + array_iterator erase(const_array_iterator pos) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: - array_value().erase(pos); - break; + case json_storage_kind::array_value: + return array_value().erase(pos); default: JSONCONS_THROW(json_runtime_error("Not an array")); - break; } } - void erase(const_array_iterator first, const_array_iterator last) + array_iterator erase(const_array_iterator first, const_array_iterator last) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: - array_value().erase(first, last); - break; + case json_storage_kind::array_value: + return array_value().erase(first, last); default: JSONCONS_THROW(json_runtime_error("Not an array")); break; @@ -4359,11 +4380,11 @@ namespace jsoncons { void erase(const string_view_type& name) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: break; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().erase(name); break; default: @@ -4375,12 +4396,12 @@ namespace jsoncons { template std::pair insert_or_assign(const string_view_type& name, T&& val) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: { auto result = object_value().insert_or_assign(name, std::forward(val)); return std::make_pair(object_iterator(result.first), result.second); @@ -4395,12 +4416,12 @@ namespace jsoncons { template std::pair try_emplace(const string_view_type& name, Args&&... args) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: { auto result = object_value().try_emplace(name, std::forward(args)...); return std::make_pair(object_iterator(result.first),result.second); @@ -4416,12 +4437,12 @@ namespace jsoncons { void merge(const basic_json& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge(source.object_value()); break; default: @@ -4433,12 +4454,12 @@ namespace jsoncons { void merge(basic_json&& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge(std::move(source.object_value())); break; default: @@ -4450,12 +4471,12 @@ namespace jsoncons { void merge(object_iterator hint, const basic_json& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge(hint, source.object_value()); break; default: @@ -4467,12 +4488,12 @@ namespace jsoncons { void merge(object_iterator hint, basic_json&& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge(hint, std::move(source.object_value())); break; default: @@ -4486,12 +4507,12 @@ namespace jsoncons { void merge_or_update(const basic_json& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge_or_update(source.object_value()); break; default: @@ -4503,12 +4524,12 @@ namespace jsoncons { void merge_or_update(basic_json&& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge_or_update(std::move(source.object_value())); break; default: @@ -4520,12 +4541,12 @@ namespace jsoncons { void merge_or_update(object_iterator hint, const basic_json& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge_or_update(hint, source.object_value()); break; default: @@ -4537,12 +4558,12 @@ namespace jsoncons { void merge_or_update(object_iterator hint, basic_json&& source) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: object_value().merge_or_update(hint, std::move(source.object_value())); break; default: @@ -4555,12 +4576,12 @@ namespace jsoncons { template object_iterator insert_or_assign(object_iterator hint, const string_view_type& name, T&& val) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: return object_iterator(object_value().insert_or_assign(hint, name, std::forward(val))); default: { @@ -4572,12 +4593,12 @@ namespace jsoncons { template object_iterator try_emplace(object_iterator hint, const string_view_type& name, Args&&... args) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: return object_iterator(object_value().try_emplace(hint, name, std::forward(args)...)); default: { @@ -4589,9 +4610,9 @@ namespace jsoncons { template array_iterator insert(const_array_iterator pos, T&& val) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return array_value().insert(pos, std::forward(val)); break; default: @@ -4604,9 +4625,9 @@ namespace jsoncons { template array_iterator insert(const_array_iterator pos, InputIt first, InputIt last) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return array_value().insert(pos, first, last); break; default: @@ -4619,10 +4640,10 @@ namespace jsoncons { template void insert(InputIt first, InputIt last) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: - case storage_kind::object_value: + case json_storage_kind::empty_object_value: + case json_storage_kind::object_value: object_value().insert(first, last, get_key_value()); break; default: @@ -4635,10 +4656,10 @@ namespace jsoncons { template void insert(sorted_unique_range_tag tag, InputIt first, InputIt last) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: - case storage_kind::object_value: + case json_storage_kind::empty_object_value: + case json_storage_kind::object_value: object_value().insert(tag, first, last, get_key_value()); break; default: @@ -4651,9 +4672,9 @@ namespace jsoncons { template array_iterator emplace(const_array_iterator pos, Args&&... args) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return array_value().emplace(pos, std::forward(args)...); break; default: @@ -4666,9 +4687,9 @@ namespace jsoncons { template basic_json& emplace_back(Args&&... args) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return array_value().emplace_back(std::forward(args)...); default: { @@ -4685,9 +4706,9 @@ namespace jsoncons { template void push_back(T&& val) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: array_value().push_back(std::forward(val)); break; default: @@ -4700,14 +4721,14 @@ namespace jsoncons { template T get_with_default(const string_view_type& key, const T& default_value) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::null_value: - case storage_kind::empty_object_value: + case json_storage_kind::null_value: + case json_storage_kind::empty_object_value: { return default_value; } - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(key); if (it != object_value().end()) @@ -4719,7 +4740,7 @@ namespace jsoncons { return default_value; } } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->get_with_default(key, default_value); default: { @@ -4731,14 +4752,14 @@ namespace jsoncons { template> T get_with_default(const string_view_type& key, const char_type* default_value) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::null_value: - case storage_kind::empty_object_value: + case json_storage_kind::null_value: + case json_storage_kind::empty_object_value: { return T(default_value); } - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(key); if (it != object_value().end()) @@ -4750,7 +4771,7 @@ namespace jsoncons { return T(default_value); } } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->get_with_default(key, default_value); default: { @@ -4966,9 +4987,9 @@ namespace jsoncons { JSONCONS_DEPRECATED_MSG("No replacement") std::size_t precision() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::double_value: + case json_storage_kind::double_value: return 0; default: JSONCONS_THROW(json_runtime_error("Not a double")); @@ -4978,9 +4999,9 @@ namespace jsoncons { JSONCONS_DEPRECATED_MSG("No replacement") std::size_t decimal_places() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::double_value: + case json_storage_kind::double_value: return 0; default: JSONCONS_THROW(json_runtime_error("Not a double")); @@ -5014,9 +5035,9 @@ namespace jsoncons { JSONCONS_DEPRECATED_MSG("No replacement") std::size_t double_precision() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::double_value: + case json_storage_kind::double_value: return 0; default: JSONCONS_THROW(json_runtime_error("Not a double")); @@ -5128,13 +5149,13 @@ namespace jsoncons { JSONCONS_DEPRECATED_MSG("Instead, use get_with_default(const string_view_type&, T&&)") basic_json get(const string_view_type& name, T&& default_value) const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: { return basic_json(std::forward(default_value)); } - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(name); if (it != object_value().end()) @@ -5158,11 +5179,11 @@ namespace jsoncons { { static const basic_json a_null = null_type(); - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return a_null; - case storage_kind::object_value: + case json_storage_kind::object_value: { auto it = object_value().find(name); return it != object_value().end() ? it->value() : a_null; @@ -5231,9 +5252,9 @@ namespace jsoncons { JSONCONS_DEPRECATED_MSG("Instead, use erase(const_object_iterator, const_object_iterator)") void remove_range(std::size_t from_index, std::size_t to_index) { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: array_value().remove_range(from_index, to_index); break; default: @@ -5289,20 +5310,20 @@ namespace jsoncons { return array_range(); } - JSONCONS_DEPRECATED_MSG("Instead, use storage()") - storage_kind get_stor_type() const + JSONCONS_DEPRECATED_MSG("Instead, use storage_kind()") + json_storage_kind get_stor_type() const { - return storage(); + return storage_kind(); } #endif range object_range() { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return range(object_iterator(), object_iterator()); - case storage_kind::object_value: + case json_storage_kind::object_value: return range(object_iterator(object_value().begin()), object_iterator(object_value().end())); default: @@ -5312,14 +5333,14 @@ namespace jsoncons { range object_range() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: return range(const_object_iterator(), const_object_iterator()); - case storage_kind::object_value: + case json_storage_kind::object_value: return range(const_object_iterator(object_value().begin()), const_object_iterator(object_value().end())); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->object_range(); default: JSONCONS_THROW(json_runtime_error("Not an object")); @@ -5328,9 +5349,9 @@ namespace jsoncons { range array_range() { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return range(array_value().begin(),array_value().end()); default: JSONCONS_THROW(json_runtime_error("Not an array")); @@ -5339,11 +5360,11 @@ namespace jsoncons { range array_range() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return range(array_value().begin(),array_value().end()); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->array_range(); default: JSONCONS_THROW(json_runtime_error("Not an array")); @@ -5352,9 +5373,9 @@ namespace jsoncons { array& array_value() { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return cast().value(); default: JSONCONS_THROW(json_runtime_error("Bad array cast")); @@ -5364,11 +5385,11 @@ namespace jsoncons { const array& array_value() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: return cast().value(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->array_value(); default: JSONCONS_THROW(json_runtime_error("Bad array cast")); @@ -5378,12 +5399,12 @@ namespace jsoncons { object& object_value() { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: create_object_implicitly(); JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: return cast().value(); default: JSONCONS_THROW(json_runtime_error("Bad object cast")); @@ -5393,14 +5414,14 @@ namespace jsoncons { const object& object_value() const { - switch (storage()) + switch (storage_kind()) { - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: const_cast(this)->create_object_implicitly(); // HERE JSONCONS_FALLTHROUGH; - case storage_kind::object_value: + case json_storage_kind::object_value: return cast().value(); - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->object_value(); default: JSONCONS_THROW(json_runtime_error("Bad object cast")); @@ -5413,13 +5434,13 @@ namespace jsoncons { void dump_noflush(basic_json_visitor& visitor, std::error_code& ec) const { const ser_context context{}; - switch (storage()) + switch (storage_kind()) { - case storage_kind::short_string_value: - case storage_kind::long_string_value: + case json_storage_kind::short_string_value: + case json_storage_kind::long_string_value: visitor.string_value(as_string_view(), tag(), context, ec); break; - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: if (tag() == semantic_tag::ext) { visitor.byte_string_value(as_byte_string_view(), ext_tag(), context, ec); @@ -5429,30 +5450,30 @@ namespace jsoncons { visitor.byte_string_value(as_byte_string_view(), tag(), context, ec); } break; - case storage_kind::half_value: + case json_storage_kind::half_value: visitor.half_value(cast().value(), tag(), context, ec); break; - case storage_kind::double_value: + case json_storage_kind::double_value: visitor.double_value(cast().value(), tag(), context, ec); break; - case storage_kind::int64_value: + case json_storage_kind::int64_value: visitor.int64_value(cast().value(), tag(), context, ec); break; - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: visitor.uint64_value(cast().value(), tag(), context, ec); break; - case storage_kind::bool_value: + case json_storage_kind::bool_value: visitor.bool_value(cast().value(), tag(), context, ec); break; - case storage_kind::null_value: + case json_storage_kind::null_value: visitor.null_value(tag(), context, ec); break; - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: visitor.begin_object(0, tag(), context, ec); visitor.end_object(context, ec); break; - case storage_kind::object_value: + case json_storage_kind::object_value: { bool more = visitor.begin_object(size(), tag(), context, ec); const object& o = object_value(); @@ -5467,7 +5488,7 @@ namespace jsoncons { } break; } - case storage_kind::array_value: + case json_storage_kind::array_value: { bool more = visitor.begin_array(size(), tag(), context, ec); const array& o = array_value(); @@ -5481,7 +5502,7 @@ namespace jsoncons { } break; } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return cast().value()->dump_noflush(visitor, ec); default: break; @@ -5510,9 +5531,9 @@ namespace jsoncons { friend basic_json deep_copy(const basic_json& other) { - switch (other.storage()) + switch (other.storage_kind()) { - case storage_kind::array_value: + case json_storage_kind::array_value: { basic_json j(json_array_arg, other.tag(), other.get_allocator()); j.reserve(other.size()); @@ -5523,7 +5544,7 @@ namespace jsoncons { } return j; } - case storage_kind::object_value: + case json_storage_kind::object_value: { basic_json j(json_object_arg, other.tag(), other.get_allocator()); j.reserve(other.size()); @@ -5534,7 +5555,7 @@ namespace jsoncons { } return j; } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: return deep_copy(*(other.cast().value())); default: return other; @@ -5774,11 +5795,11 @@ namespace jsoncons { using json = basic_json>; using wjson = basic_json>; - using ojson = basic_json>; - using wojson = basic_json>; + using ojson = basic_json>; + using wojson = basic_json>; #if !defined(JSONCONS_NO_DEPRECATED) - JSONCONS_DEPRECATED_MSG("Instead, use wojson") typedef basic_json> owjson; + JSONCONS_DEPRECATED_MSG("Instead, use wojson") typedef basic_json> owjson; JSONCONS_DEPRECATED_MSG("Instead, use json_decoder") typedef json_decoder json_deserializer; JSONCONS_DEPRECATED_MSG("Instead, use json_decoder") typedef json_decoder wjson_deserializer; JSONCONS_DEPRECATED_MSG("Instead, use json_decoder") typedef json_decoder ojson_deserializer; diff --git a/module/lib/jsoncons/config/compiler_support.hpp b/module/lib/jsoncons/config/compiler_support.hpp index 51b388d3..d8cc823d 100644 --- a/module/lib/jsoncons/config/compiler_support.hpp +++ b/module/lib/jsoncons/config/compiler_support.hpp @@ -218,10 +218,10 @@ #if !defined(JSONCONS_HAS_STD_MAKE_UNIQUE) #if defined(__clang__) && defined(__cplusplus) #if defined(__APPLE__) - #if __clang_major__ >= 6 && __cplusplus >= 201103L // Xcode 6 + #if __clang_major__ >= 6 && __cplusplus >= 201402L // Xcode 6 #define JSONCONS_HAS_STD_MAKE_UNIQUE #endif - #elif ((__clang_major__*100 +__clang_minor__) >= 340) && __cplusplus > 201103L + #elif ((__clang_major__*100 +__clang_minor__) >= 340) && __cplusplus >= 201402L #define JSONCONS_HAS_STD_MAKE_UNIQUE #endif #elif defined(__GNUC__) diff --git a/module/lib/jsoncons/config/jsoncons_config.hpp b/module/lib/jsoncons/config/jsoncons_config.hpp index c70a9536..63c437b3 100644 --- a/module/lib/jsoncons/config/jsoncons_config.hpp +++ b/module/lib/jsoncons/config/jsoncons_config.hpp @@ -242,18 +242,58 @@ namespace binary { } // binary } // jsoncons +namespace jsoncons { + + template + constexpr const CharT* cstring_constant_of_type(const char* c, const wchar_t* w); + + template<> inline + constexpr const char* cstring_constant_of_type(const char* c, const wchar_t*) + { + return c; + } + template<> inline + constexpr const wchar_t* cstring_constant_of_type(const char*, const wchar_t* w) + { + return w; + } + + template + std::basic_string string_constant_of_type(const char* c, const wchar_t* w); + + template<> inline + std::string string_constant_of_type(const char* c, const wchar_t*) + { + return std::string(c); + } + template<> inline + std::wstring string_constant_of_type(const char*, const wchar_t* w) + { + return std::wstring(w); + } + + template + jsoncons::basic_string_view string_view_constant_of_type(const char* c, const wchar_t* w); + + template<> inline + jsoncons::string_view string_view_constant_of_type(const char* c, const wchar_t*) + { + return jsoncons::string_view(c); + } + template<> inline + jsoncons::wstring_view string_view_constant_of_type(const char*, const wchar_t* w) + { + return jsoncons::wstring_view(w); + } + +} // jsoncons + #define JSONCONS_EXPAND(X) X #define JSONCONS_QUOTE(Prefix, A) JSONCONS_EXPAND(Prefix ## #A) -#define JSONCONS_STRING_LITERAL(name, ...) \ - template \ - jsoncons::basic_string_view name() {\ - static constexpr CharT s[] = { __VA_ARGS__};\ - return jsoncons::basic_string_view(s, sizeof(s) / sizeof(CharT));\ - } - -#define JSONCONS_CSTRING(CharT, name, ...) \ - static constexpr CharT name[] = { __VA_ARGS__,0}; +#define JSONCONS_CSTRING_CONSTANT(CharT, Str) cstring_constant_of_type(Str, JSONCONS_QUOTE(L, Str)) +#define JSONCONS_STRING_CONSTANT(CharT, Str) string_constant_of_type(Str, JSONCONS_QUOTE(L, Str)) +#define JSONCONS_STRING_VIEW_CONSTANT(CharT, Str) string_view_constant_of_type(Str, JSONCONS_QUOTE(L, Str)) #if defined(__clang__) #define JSONCONS_HAS_STD_REGEX 1 diff --git a/module/lib/jsoncons/config/version.hpp b/module/lib/jsoncons/config/version.hpp index b6023813..7f11eef4 100644 --- a/module/lib/jsoncons/config/version.hpp +++ b/module/lib/jsoncons/config/version.hpp @@ -11,7 +11,7 @@ #define JSONCONS_VERSION_MAJOR 0 #define JSONCONS_VERSION_MINOR 168 -#define JSONCONS_VERSION_PATCH 1 +#define JSONCONS_VERSION_PATCH 7 namespace jsoncons { diff --git a/module/lib/jsoncons/converter.hpp b/module/lib/jsoncons/converter.hpp index 12df08e3..15d19178 100644 --- a/module/lib/jsoncons/converter.hpp +++ b/module/lib/jsoncons/converter.hpp @@ -223,35 +223,35 @@ namespace jsoncons { JSONCONS_CPP14_CONSTEXPR Into from(bool val, semantic_tag, std::error_code&) const { - constexpr char_type true_literal[] = {'t','r','u','e'}; - constexpr char_type false_literal[] = {'f','a','l','s','e'}; + constexpr const char_type* true_constant = JSONCONS_CSTRING_CONSTANT(char_type,"true"); + constexpr const char_type* false_constant = JSONCONS_CSTRING_CONSTANT(char_type,"false"); - return val ? Into(true_literal,4) : Into(false_literal,5); + return val ? Into(true_constant,4) : Into(false_constant,5); } JSONCONS_CPP14_CONSTEXPR Into from(bool val, semantic_tag, const allocator_type& alloc, std::error_code&) const { - constexpr char_type true_literal[] = {'t','r','u','e'}; - constexpr char_type false_literal[] = {'f','a','l','s','e'}; + constexpr const char_type* true_constant = JSONCONS_CSTRING_CONSTANT(char_type,"true"); + constexpr const char_type* false_constant = JSONCONS_CSTRING_CONSTANT(char_type,"false"); - return val ? Into(true_literal,4,alloc) : Into(false_literal,5,alloc); + return val ? Into(true_constant,4,alloc) : Into(false_constant,5,alloc); } JSONCONS_CPP14_CONSTEXPR Into from(null_type, semantic_tag, std::error_code&) const { - constexpr char_type null_literal[] = {'n','u','l','l'}; + constexpr const char_type* null_constant = JSONCONS_CSTRING_CONSTANT(char_type,"null"); - return Into(null_literal,4); + return Into(null_constant,4); } JSONCONS_CPP14_CONSTEXPR Into from(null_type, semantic_tag, const allocator_type& alloc, std::error_code&) const { - constexpr char_type null_literal[] = {'n','u','l','l'}; + constexpr const char_type* null_constant = JSONCONS_CSTRING_CONSTANT(char_type,"null"); - return Into(null_literal,4,alloc); + return Into(null_constant,4,alloc); } private: diff --git a/module/lib/jsoncons/decode_traits.hpp b/module/lib/jsoncons/decode_traits.hpp index 2177e4e1..d237b323 100644 --- a/module/lib/jsoncons/decode_traits.hpp +++ b/module/lib/jsoncons/decode_traits.hpp @@ -33,7 +33,11 @@ namespace jsoncons { { decoder.reset(); cursor.read_to(decoder, ec); - if (!decoder.is_valid()) + if (ec) + { + JSONCONS_THROW(ser_error(ec, cursor.context().line(), cursor.context().column())); + } + else if (!decoder.is_valid()) { JSONCONS_THROW(ser_error(conv_errc::conversion_failed, cursor.context().line(), cursor.context().column())); } @@ -175,6 +179,7 @@ namespace jsoncons { while (cursor.current().event_type() != staj_event_type::end_array && !ec) { v.push_back(decode_traits::decode(cursor, decoder, ec)); + if (ec) {return T{};} cursor.next(ec); } return v; @@ -415,7 +420,9 @@ namespace jsoncons { while (cursor.current().event_type() != staj_event_type::end_array && !ec) { v.insert(decode_traits::decode(cursor, decoder, ec)); + if (ec) {return T{};} cursor.next(ec); + if (ec) {return T{};} } return v; } @@ -450,7 +457,9 @@ namespace jsoncons { for (std::size_t i = 0; i < N && cursor.current().event_type() != staj_event_type::end_array && !ec; ++i) { v[i] = decode_traits::decode(cursor, decoder, ec); + if (ec) {return v;} cursor.next(ec); + if (ec) {return v;} } return v; } @@ -494,7 +503,9 @@ namespace jsoncons { cursor.next(ec); if (ec) return val; val.emplace(std::move(key),decode_traits::decode(cursor, decoder, ec)); + if (ec) {return val;} cursor.next(ec); + if (ec) {return val;} } return val; } @@ -543,7 +554,9 @@ namespace jsoncons { cursor.next(ec); if (ec) return val; val.emplace(n, decode_traits::decode(cursor, decoder, ec)); + if (ec) {return val;} cursor.next(ec); + if (ec) {return val;} } return val; } diff --git a/module/lib/jsoncons/detail/parse_number.hpp b/module/lib/jsoncons/detail/parse_number.hpp index be0ec48f..8da425a9 100644 --- a/module/lib/jsoncons/detail/parse_number.hpp +++ b/module/lib/jsoncons/detail/parse_number.hpp @@ -78,12 +78,12 @@ struct to_integer_result { const CharT* ptr; to_integer_errc ec; - constexpr to_integer_result(const CharT* ptr) - : ptr(ptr), ec(to_integer_errc()) + constexpr to_integer_result(const CharT* ptr_) + : ptr(ptr_), ec(to_integer_errc()) { } - constexpr to_integer_result(const CharT* ptr, to_integer_errc ec) - : ptr(ptr), ec(ec) + constexpr to_integer_result(const CharT* ptr_, to_integer_errc ec_) + : ptr(ptr_), ec(ec_) { } diff --git a/module/lib/jsoncons/detail/string_view.hpp b/module/lib/jsoncons/detail/string_view.hpp index 1fde07fe..fc568a1c 100644 --- a/module/lib/jsoncons/detail/string_view.hpp +++ b/module/lib/jsoncons/detail/string_view.hpp @@ -47,18 +47,27 @@ namespace detail { : data_(data), length_(length) { } - constexpr basic_string_view(const CharT* data) + + basic_string_view(const CharT* data) : data_(data), length_(Traits::length(data)) { } constexpr basic_string_view(const basic_string_view& other) noexcept = default; template - basic_string_view(const std::basic_string& s) noexcept + JSONCONS_CPP14_CONSTEXPR basic_string_view(const std::basic_string& s) noexcept : data_(s.data()), length_(s.length()) { } + JSONCONS_CPP14_CONSTEXPR basic_string_view& operator=( const basic_string_view& view ) noexcept + { + data_ = view.data(); + length_ = view.length(); + + return *this; + } + template explicit operator std::basic_string() const { diff --git a/module/lib/jsoncons/detail/string_wrapper.hpp b/module/lib/jsoncons/detail/string_wrapper.hpp index 1526b41a..88634b01 100644 --- a/module/lib/jsoncons/detail/string_wrapper.hpp +++ b/module/lib/jsoncons/detail/string_wrapper.hpp @@ -98,7 +98,7 @@ namespace detail { str_t data; char_type c[1]; }; - typedef typename std::aligned_storage::type storage_kind; + typedef typename std::aligned_storage::type json_storage_kind; string_pointer ptr_; public: @@ -159,7 +159,7 @@ namespace detail { private: static size_t aligned_size(std::size_t n) { - return sizeof(storage_kind) + n; + return sizeof(json_storage_kind) + n; } static string_pointer create(const char_type* s, std::size_t length, const Allocator& alloc) @@ -263,7 +263,7 @@ namespace detail { str_t data; char_type c[1]; }; - typedef typename std::aligned_storage::type storage_kind; + typedef typename std::aligned_storage::type json_storage_kind; string_pointer ptr_; public: @@ -329,7 +329,7 @@ namespace detail { private: static size_t aligned_size(std::size_t n) { - return sizeof(storage_kind) + n; + return sizeof(json_storage_kind) + n; } static string_pointer create(const char_type* s, std::size_t length, uint64_t tag, const Allocator& alloc) diff --git a/module/lib/jsoncons/json_array.hpp b/module/lib/jsoncons/json_array.hpp new file mode 100644 index 00000000..120b0790 --- /dev/null +++ b/module/lib/jsoncons/json_array.hpp @@ -0,0 +1,324 @@ +// Copyright 2013 Daniel Parker +// Distributed under the Boost license, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See https://github.com/danielaparker/jsoncons for latest version + +#ifndef JSONCONS_JSON_ARRAY_HPP +#define JSONCONS_JSON_ARRAY_HPP + +#include +#include +#include +#include +#include // std::sort, std::stable_sort, std::lower_bound, std::unique +#include +#include +#include // std::iterator_traits +#include // std::allocator +#include // std::move +#include // assert +#include // std::enable_if +#include +#include + +namespace jsoncons { + + // json_array + + template class SequenceContainer = std::vector> + class json_array : public allocator_holder + { + public: + using allocator_type = typename Json::allocator_type; + using value_type = Json; + private: + using value_allocator_type = typename std::allocator_traits:: template rebind_alloc; + using value_container_type = SequenceContainer; + value_container_type elements_; + public: + using iterator = typename value_container_type::iterator; + using const_iterator = typename value_container_type::const_iterator; + using reference = typename std::iterator_traits::reference; + using const_reference = typename std::iterator_traits::reference; + + using allocator_holder::get_allocator; + + json_array() + { + } + + explicit json_array(const allocator_type& alloc) + : allocator_holder(alloc), + elements_(value_allocator_type(alloc)) + { + } + + explicit json_array(std::size_t n, + const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(n,Json(),value_allocator_type(alloc)) + { + } + + explicit json_array(std::size_t n, + const Json& value, + const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(n,value,value_allocator_type(alloc)) + { + } + + template + json_array(InputIterator begin, InputIterator end, const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(begin,end,value_allocator_type(alloc)) + { + } + json_array(const json_array& val) + : allocator_holder(val.get_allocator()), + elements_(val.elements_) + { + } + json_array(const json_array& val, const allocator_type& alloc) + : allocator_holder(alloc), + elements_(val.elements_,value_allocator_type(alloc)) + { + } + + json_array(json_array&& val) noexcept + : allocator_holder(val.get_allocator()), + elements_(std::move(val.elements_)) + { + } + json_array(json_array&& val, const allocator_type& alloc) + : allocator_holder(alloc), + elements_(std::move(val.elements_),value_allocator_type(alloc)) + { + } + + json_array(const std::initializer_list& init, + const allocator_type& alloc = allocator_type()) + : allocator_holder(alloc), + elements_(init,value_allocator_type(alloc)) + { + } + ~json_array() noexcept + { + flatten_and_destroy(); + } + + reference back() + { + return elements_.back(); + } + + const_reference back() const + { + return elements_.back(); + } + + void pop_back() + { + elements_.pop_back(); + } + + bool empty() const + { + return elements_.empty(); + } + + void swap(json_array& val) noexcept + { + elements_.swap(val.elements_); + } + + std::size_t size() const {return elements_.size();} + + std::size_t capacity() const {return elements_.capacity();} + + void clear() {elements_.clear();} + + void shrink_to_fit() + { + for (std::size_t i = 0; i < elements_.size(); ++i) + { + elements_[i].shrink_to_fit(); + } + elements_.shrink_to_fit(); + } + + void reserve(std::size_t n) {elements_.reserve(n);} + + void resize(std::size_t n) {elements_.resize(n);} + + void resize(std::size_t n, const Json& val) {elements_.resize(n,val);} + + #if !defined(JSONCONS_NO_DEPRECATED) + JSONCONS_DEPRECATED_MSG("Instead, use erase(const_iterator, const_iterator)") + void remove_range(std::size_t from_index, std::size_t to_index) + { + JSONCONS_ASSERT(from_index <= to_index); + JSONCONS_ASSERT(to_index <= elements_.size()); + elements_.erase(elements_.cbegin()+from_index,elements_.cbegin()+to_index); + } + #endif + + iterator erase(const_iterator pos) + { + #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.erase(it); + #else + return elements_.erase(pos); + #endif + } + + iterator erase(const_iterator first, const_iterator last) + { + #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it1 = elements_.begin() + (first - elements_.begin()); + iterator it2 = elements_.begin() + (last - elements_.begin()); + return elements_.erase(it1,it2); + #else + return elements_.erase(first,last); + #endif + } + + Json& operator[](std::size_t i) {return elements_[i];} + + const Json& operator[](std::size_t i) const {return elements_[i];} + + // push_back + + template + typename std::enable_if::value,void>::type + push_back(T&& value) + { + elements_.emplace_back(std::forward(value)); + } + + template + typename std::enable_if::value,void>::type + push_back(T&& value) + { + elements_.emplace_back(std::forward(value),get_allocator()); + } + + template + typename std::enable_if::value,iterator>::type + insert(const_iterator pos, T&& value) + { + #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(value)); + #else + return elements_.emplace(pos, std::forward(value)); + #endif + } + template + typename std::enable_if::value,iterator>::type + insert(const_iterator pos, T&& value) + { + #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(value), get_allocator()); + #else + return elements_.emplace(pos, std::forward(value), get_allocator()); + #endif + } + + template + iterator insert(const_iterator pos, InputIt first, InputIt last) + { + #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + elements_.insert(it, first, last); + return first == last ? it : it + 1; + #else + return elements_.insert(pos, first, last); + #endif + } + + template + typename std::enable_if::value,iterator>::type + emplace(const_iterator pos, Args&&... args) + { + #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = elements_.begin() + (pos - elements_.begin()); + return elements_.emplace(it, std::forward(args)...); + #else + return elements_.emplace(pos, std::forward(args)...); + #endif + } + + template + Json& emplace_back(Args&&... args) + { + elements_.emplace_back(std::forward(args)...); + return elements_.back(); + } + + iterator begin() {return elements_.begin();} + + iterator end() {return elements_.end();} + + const_iterator begin() const {return elements_.begin();} + + const_iterator end() const {return elements_.end();} + + bool operator==(const json_array& rhs) const noexcept + { + return elements_ == rhs.elements_; + } + + bool operator<(const json_array& rhs) const noexcept + { + return elements_ < rhs.elements_; + } + private: + + json_array& operator=(const json_array&) = delete; + + void flatten_and_destroy() noexcept + { + while (!elements_.empty()) + { + value_type current = std::move(elements_.back()); + elements_.pop_back(); + switch (current.storage_kind()) + { + case json_storage_kind::array_value: + { + for (auto&& item : current.array_range()) + { + if (item.size() > 0) // non-empty object or array + { + elements_.push_back(std::move(item)); + } + } + current.clear(); + break; + } + case json_storage_kind::object_value: + { + for (auto&& kv : current.object_range()) + { + if (kv.value().size() > 0) // non-empty object or array + { + elements_.push_back(std::move(kv.value())); + } + } + current.clear(); + break; + } + default: + break; + } + } + } + }; + +} // namespace jsoncons + +#endif diff --git a/module/lib/jsoncons/json_encoder.hpp b/module/lib/jsoncons/json_encoder.hpp index fc179d98..7701d2bc 100644 --- a/module/lib/jsoncons/json_encoder.hpp +++ b/module/lib/jsoncons/json_encoder.hpp @@ -191,19 +191,19 @@ namespace detail { template,class Allocator=std::allocator> class basic_json_encoder final : public basic_json_visitor { - static const std::array& null_k() + static const jsoncons::basic_string_view null_constant() { - static constexpr std::array k{'n','u','l','l'}; + static const jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT, "null"); return k; } - static const std::array& true_k() + static const jsoncons::basic_string_view true_constant() { - static constexpr std::array k{'t','r','u','e'}; + static const jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT, "true"); return k; } - static const std::array& false_k() + static const jsoncons::basic_string_view false_constant() { - static constexpr std::array k{'f','a','l','s','e'}; + static const jsoncons::basic_string_view k = JSONCONS_STRING_VIEW_CONSTANT(CharT, "false"); return k; } public: @@ -638,8 +638,8 @@ namespace detail { } } - sink_.append(null_k().data(), null_k().size()); - column_ += null_k().size(); + sink_.append(null_constant().data(), null_constant().size()); + column_ += null_constant().size(); end_value(); return true; @@ -783,8 +783,8 @@ namespace detail { } else { - sink_.append(null_k().data(), null_k().size()); - column_ += null_k().size(); + sink_.append(null_constant().data(), null_constant().size()); + column_ += null_constant().size(); } } else if (value == std::numeric_limits::infinity()) @@ -800,8 +800,8 @@ namespace detail { } else { - sink_.append(null_k().data(), null_k().size()); - column_ += null_k().size(); + sink_.append(null_constant().data(), null_constant().size()); + column_ += null_constant().size(); } } else @@ -817,8 +817,8 @@ namespace detail { } else { - sink_.append(null_k().data(), null_k().size()); - column_ += null_k().size(); + sink_.append(null_constant().data(), null_constant().size()); + column_ += null_constant().size(); } } } @@ -892,13 +892,13 @@ namespace detail { if (value) { - sink_.append(true_k().data(), true_k().size()); - column_ += true_k().size(); + sink_.append(true_constant().data(), true_constant().size()); + column_ += true_constant().size(); } else { - sink_.append(false_k().data(), false_k().size()); - column_ += false_k().size(); + sink_.append(false_constant().data(), false_constant().size()); + column_ += false_constant().size(); } end_value(); @@ -1037,17 +1037,17 @@ namespace detail { template,class Allocator=std::allocator> class basic_compact_json_encoder final : public basic_json_visitor { - static const std::array& null_k() + static const std::array& null_constant() { static constexpr std::array k{'n','u','l','l'}; return k; } - static const std::array& true_k() + static const std::array& true_constant() { static constexpr std::array k{'t','r','u','e'}; return k; } - static const std::array& false_k() + static const std::array& false_constant() { static constexpr std::array k{'f','a','l','s','e'}; return k; @@ -1222,7 +1222,7 @@ namespace detail { sink_.push_back(','); } - sink_.append(null_k().data(), null_k().size()); + sink_.append(null_constant().data(), null_constant().size()); if (!stack_.empty()) { @@ -1410,7 +1410,7 @@ namespace detail { } else { - sink_.append(null_k().data(), null_k().size()); + sink_.append(null_constant().data(), null_constant().size()); } } else if (value == std::numeric_limits::infinity()) @@ -1425,7 +1425,7 @@ namespace detail { } else { - sink_.append(null_k().data(), null_k().size()); + sink_.append(null_constant().data(), null_constant().size()); } } else @@ -1440,7 +1440,7 @@ namespace detail { } else { - sink_.append(null_k().data(), null_k().size()); + sink_.append(null_constant().data(), null_constant().size()); } } } @@ -1499,11 +1499,11 @@ namespace detail { if (value) { - sink_.append(true_k().data(), true_k().size()); + sink_.append(true_constant().data(), true_constant().size()); } else { - sink_.append(false_k().data(), false_k().size()); + sink_.append(false_constant().data(), false_constant().size()); } if (!stack_.empty()) diff --git a/module/lib/jsoncons/json_container_types.hpp b/module/lib/jsoncons/json_object.hpp similarity index 72% rename from module/lib/jsoncons/json_container_types.hpp rename to module/lib/jsoncons/json_object.hpp index ced66e68..dba0c371 100644 --- a/module/lib/jsoncons/json_container_types.hpp +++ b/module/lib/jsoncons/json_object.hpp @@ -4,8 +4,8 @@ // See https://github.com/danielaparker/jsoncons for latest version -#ifndef JSONCONS_JSON_CONTAINER_TYPES_HPP -#define JSONCONS_JSON_CONTAINER_TYPES_HPP +#ifndef JSONCONS_JSON_OBJECT_HPP +#define JSONCONS_JSON_OBJECT_HPP #include #include @@ -21,311 +21,15 @@ #include // std::enable_if #include #include +#include namespace jsoncons { - // json_array - - template - class json_array : public allocator_holder - { - public: - using allocator_type = typename Json::allocator_type; - using value_type = Json; - using implementation_policy = typename Json::implementation_policy; - private: - using value_allocator_type = typename std::allocator_traits:: template rebind_alloc; - using value_container_type = typename implementation_policy::template sequence_container_type; - value_container_type elements_; - public: - using iterator = typename value_container_type::iterator; - using const_iterator = typename value_container_type::const_iterator; - using reference = typename std::iterator_traits::reference; - using const_reference = typename std::iterator_traits::reference; - - using allocator_holder::get_allocator; - - json_array() - { - } - - explicit json_array(const allocator_type& alloc) - : allocator_holder(alloc), - elements_(value_allocator_type(alloc)) - { - } - - explicit json_array(std::size_t n, - const allocator_type& alloc = allocator_type()) - : allocator_holder(alloc), - elements_(n,Json(),value_allocator_type(alloc)) - { - } - - explicit json_array(std::size_t n, - const Json& value, - const allocator_type& alloc = allocator_type()) - : allocator_holder(alloc), - elements_(n,value,value_allocator_type(alloc)) - { - } - - template - json_array(InputIterator begin, InputIterator end, const allocator_type& alloc = allocator_type()) - : allocator_holder(alloc), - elements_(begin,end,value_allocator_type(alloc)) - { - } - json_array(const json_array& val) - : allocator_holder(val.get_allocator()), - elements_(val.elements_) - { - } - json_array(const json_array& val, const allocator_type& alloc) - : allocator_holder(alloc), - elements_(val.elements_,value_allocator_type(alloc)) - { - } - - json_array(json_array&& val) noexcept - : allocator_holder(val.get_allocator()), - elements_(std::move(val.elements_)) - { - } - json_array(json_array&& val, const allocator_type& alloc) - : allocator_holder(alloc), - elements_(std::move(val.elements_),value_allocator_type(alloc)) - { - } - - json_array(const std::initializer_list& init, - const allocator_type& alloc = allocator_type()) - : allocator_holder(alloc), - elements_(init,value_allocator_type(alloc)) - { - } - ~json_array() noexcept - { - destroy(); - } - - reference back() - { - return elements_.back(); - } - - const_reference back() const - { - return elements_.back(); - } - - void pop_back() - { - elements_.pop_back(); - } - - bool empty() const - { - return elements_.empty(); - } - - void swap(json_array& val) noexcept - { - elements_.swap(val.elements_); - } - - std::size_t size() const {return elements_.size();} - - std::size_t capacity() const {return elements_.capacity();} - - void clear() {elements_.clear();} - - void shrink_to_fit() - { - for (std::size_t i = 0; i < elements_.size(); ++i) - { - elements_[i].shrink_to_fit(); - } - elements_.shrink_to_fit(); - } - - void reserve(std::size_t n) {elements_.reserve(n);} - - void resize(std::size_t n) {elements_.resize(n);} - - void resize(std::size_t n, const Json& val) {elements_.resize(n,val);} - - #if !defined(JSONCONS_NO_DEPRECATED) - JSONCONS_DEPRECATED_MSG("Instead, use erase(const_iterator, const_iterator)") - void remove_range(std::size_t from_index, std::size_t to_index) - { - JSONCONS_ASSERT(from_index <= to_index); - JSONCONS_ASSERT(to_index <= elements_.size()); - elements_.erase(elements_.cbegin()+from_index,elements_.cbegin()+to_index); - } - #endif - void erase(const_iterator pos) - { - #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) - iterator it = elements_.begin() + (pos - elements_.begin()); - elements_.erase(it); - #else - elements_.erase(pos); - #endif - } - - void erase(const_iterator first, const_iterator last) - { - #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) - iterator it1 = elements_.begin() + (first - elements_.begin()); - iterator it2 = elements_.begin() + (last - elements_.begin()); - elements_.erase(it1,it2); - #else - elements_.erase(first,last); - #endif - } - - Json& operator[](std::size_t i) {return elements_[i];} - - const Json& operator[](std::size_t i) const {return elements_[i];} - - // push_back - - template - typename std::enable_if::value,void>::type - push_back(T&& value) - { - elements_.emplace_back(std::forward(value)); - } - - template - typename std::enable_if::value,void>::type - push_back(T&& value) - { - elements_.emplace_back(std::forward(value),get_allocator()); - } - - template - typename std::enable_if::value,iterator>::type - insert(const_iterator pos, T&& value) - { - #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) - iterator it = elements_.begin() + (pos - elements_.begin()); - return elements_.emplace(it, std::forward(value)); - #else - return elements_.emplace(pos, std::forward(value)); - #endif - } - template - typename std::enable_if::value,iterator>::type - insert(const_iterator pos, T&& value) - { - #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) - iterator it = elements_.begin() + (pos - elements_.begin()); - return elements_.emplace(it, std::forward(value), get_allocator()); - #else - return elements_.emplace(pos, std::forward(value), get_allocator()); - #endif - } - - template - iterator insert(const_iterator pos, InputIt first, InputIt last) - { - #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) - iterator it = elements_.begin() + (pos - elements_.begin()); - elements_.insert(it, first, last); - return first == last ? it : it + 1; - #else - return elements_.insert(pos, first, last); - #endif - } - - template - typename std::enable_if::value,iterator>::type - emplace(const_iterator pos, Args&&... args) - { - #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) - iterator it = elements_.begin() + (pos - elements_.begin()); - return elements_.emplace(it, std::forward(args)...); - #else - return elements_.emplace(pos, std::forward(args)...); - #endif - } - - template - Json& emplace_back(Args&&... args) - { - elements_.emplace_back(std::forward(args)...); - return elements_.back(); - } - - iterator begin() {return elements_.begin();} - - iterator end() {return elements_.end();} - - const_iterator begin() const {return elements_.begin();} - - const_iterator end() const {return elements_.end();} - - bool operator==(const json_array& rhs) const noexcept - { - return elements_ == rhs.elements_; - } - - bool operator<(const json_array& rhs) const noexcept - { - return elements_ < rhs.elements_; - } - private: - - json_array& operator=(const json_array&) = delete; - - void destroy() noexcept - { - while (!elements_.empty()) - { - value_type current = std::move(elements_.back()); - elements_.pop_back(); - switch (current.storage()) - { - case storage_kind::array_value: - { - for (auto&& item : current.array_range()) - { - if (item.size() > 0) // non-empty object or array - { - elements_.push_back(std::move(item)); - } - } - current.clear(); - break; - } - case storage_kind::object_value: - { - for (auto&& kv : current.object_range()) - { - if (kv.value().size() > 0) // non-empty object or array - { - elements_.push_back(std::move(kv.value())); - } - } - current.clear(); - break; - } - default: - break; - } - } - } - }; - struct sorted_unique_range_tag { explicit sorted_unique_range_tag() = default; }; - // json_object - // key_value template @@ -337,6 +41,7 @@ namespace jsoncons { using allocator_type = typename ValueT::allocator_type; using string_view_type = typename value_type::string_view_type; private: + key_type key_; value_type value_; public: @@ -520,27 +225,26 @@ namespace jsoncons { explicit preserve_key_order() = default; }; - template - class json_object - { - }; // Sort keys - template - class json_object::value>::type> : - public allocator_holder + template class SequenceContainer = std::vector> + class sorted_json_object : public allocator_holder { public: using allocator_type = typename Json::allocator_type; using key_type = KeyT; - //using mapped_type = Json; using key_value_type = key_value; using char_type = typename Json::char_type; using string_view_type = typename Json::string_view_type; - using implementation_policy = typename Json::implementation_policy; private: - using key_value_allocator_type = typename std::allocator_traits:: template rebind_alloc; - using key_value_container_type = typename implementation_policy::template sequence_container_type; + struct Comp + { + bool operator() (const key_value_type& kv, string_view_type k) const { return kv.key() < k; } + bool operator() (string_view_type k, const key_value_type& kv) const { return k < kv.key(); } + }; + + using key_value_allocator_type = typename std::allocator_traits:: template rebind_alloc; + using key_value_container_type = SequenceContainer; key_value_container_type members_; public: @@ -549,54 +253,54 @@ namespace jsoncons { using allocator_holder::get_allocator; - json_object() + sorted_json_object() { } - explicit json_object(const allocator_type& alloc) + explicit sorted_json_object(const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) { } - json_object(const json_object& val) + sorted_json_object(const sorted_json_object& val) : allocator_holder(val.get_allocator()), members_(val.members_) { } - json_object(json_object&& val) + sorted_json_object(sorted_json_object&& val) : allocator_holder(val.get_allocator()), members_(std::move(val.members_)) { } - json_object& operator=(const json_object& val) + sorted_json_object& operator=(const sorted_json_object& val) { allocator_holder::operator=(val.get_allocator()); members_ = val.members_; return *this; } - json_object& operator=(json_object&& val) + sorted_json_object& operator=(sorted_json_object&& val) { val.swap(*this); return *this; } - json_object(const json_object& val, const allocator_type& alloc) + sorted_json_object(const sorted_json_object& val, const allocator_type& alloc) : allocator_holder(alloc), members_(val.members_,key_value_allocator_type(alloc)) { } - json_object(json_object&& val,const allocator_type& alloc) + sorted_json_object(sorted_json_object&& val,const allocator_type& alloc) : allocator_holder(alloc), members_(std::move(val.members_),key_value_allocator_type(alloc)) { } template - json_object(InputIt first, InputIt last) + sorted_json_object(InputIt first, InputIt last) { std::size_t count = std::distance(first,last); members_.reserve(count); @@ -612,7 +316,7 @@ namespace jsoncons { } template - json_object(InputIt first, InputIt last, + sorted_json_object(InputIt first, InputIt last, const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) @@ -630,7 +334,7 @@ namespace jsoncons { members_.erase(it, members_.end()); } - json_object(const std::initializer_list,Json>>& init, + sorted_json_object(const std::initializer_list,Json>>& init, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)) @@ -642,9 +346,9 @@ namespace jsoncons { } } - ~json_object() noexcept + ~sorted_json_object() noexcept { - destroy(); + flatten_and_destroy(); } bool empty() const @@ -652,7 +356,7 @@ namespace jsoncons { return members_.empty(); } - void swap(json_object& val) noexcept + void swap(sorted_json_object& val) noexcept { members_.swap(val.members_); } @@ -714,47 +418,43 @@ namespace jsoncons { iterator find(const string_view_type& name) noexcept { - auto it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); - auto result = (it != members_.end() && it->key() == name) ? it : members_.end(); - return result; + auto p = std::equal_range(members_.begin(),members_.end(), name, + Comp()); + return p.first == p.second ? members_.end() : p.first; } const_iterator find(const string_view_type& name) const noexcept { - auto it = std::lower_bound(members_.begin(),members_.end(), - name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); - auto result = (it != members_.end() && it->key() == name) ? it : members_.end(); - return result; + auto p = std::equal_range(members_.begin(),members_.end(), name, + Comp()); + return p.first == p.second ? members_.end() : p.first; } - void erase(const_iterator pos) + iterator erase(const_iterator pos) { #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) iterator it = members_.begin() + (pos - members_.begin()); - members_.erase(it); + return members_.erase(it); #else - members_.erase(pos); + return members_.erase(pos); #endif } - void erase(const_iterator first, const_iterator last) + iterator erase(const_iterator first, const_iterator last) { #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) iterator it1 = members_.begin() + (first - members_.begin()); iterator it2 = members_.begin() + (last - members_.begin()); - members_.erase(it1,it2); + return members_.erase(it1,it2); #else - members_.erase(first,last); + return members_.erase(first,last); #endif } void erase(const string_view_type& name) { - auto it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); - if (it != members_.end() && it->key() == name) + auto it = find(name); + if (it != members_.end()) { members_.erase(it); } @@ -810,7 +510,7 @@ namespace jsoncons { { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end()), @@ -839,7 +539,7 @@ namespace jsoncons { { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), @@ -870,7 +570,7 @@ namespace jsoncons { { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end()), @@ -898,7 +598,7 @@ namespace jsoncons { { bool inserted; auto it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); if (it == members_.end()) { members_.emplace_back(key_type(name.begin(),name.end(), get_allocator()), @@ -929,12 +629,12 @@ namespace jsoncons { if (hint != members_.end() && hint->key() <= name) { it = std::lower_bound(hint,members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } else { it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } if (it == members_.end()) @@ -964,12 +664,12 @@ namespace jsoncons { if (hint != members_.end() && hint->key() <= name) { it = std::lower_bound(hint,members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } else { it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } if (it == members_.end()) @@ -1035,12 +735,12 @@ namespace jsoncons { if (hint != members_.end() && hint->key() <= name) { it = std::lower_bound(hint,members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } else { it = std::lower_bound(members_.begin(),members_.end(), name, - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } if (it == members_.end()) @@ -1064,7 +764,7 @@ namespace jsoncons { // merge - void merge(const json_object& source) + void merge(const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { @@ -1072,14 +772,14 @@ namespace jsoncons { } } - void merge(json_object&& source) + void merge(sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { auto pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); if (pos == members_.end() ) { members_.emplace_back(*it); @@ -1091,7 +791,7 @@ namespace jsoncons { } } - void merge(iterator hint, const json_object& source) + void merge(iterator hint, const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { @@ -1099,7 +799,7 @@ namespace jsoncons { } } - void merge(iterator hint, json_object&& source) + void merge(iterator hint, sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); @@ -1109,12 +809,12 @@ namespace jsoncons { if (hint != members_.end() && hint->key() <= (*it).key()) { pos = std::lower_bound(hint,members_.end(), (*it).key(), - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } else { pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } if (pos == members_.end() ) { @@ -1130,7 +830,7 @@ namespace jsoncons { // merge_or_update - void merge_or_update(const json_object& source) + void merge_or_update(const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { @@ -1138,14 +838,14 @@ namespace jsoncons { } } - void merge_or_update(json_object&& source) + void merge_or_update(sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); for (; it != end; ++it) { auto pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); if (pos == members_.end() ) { members_.emplace_back(*it); @@ -1157,7 +857,7 @@ namespace jsoncons { } } - void merge_or_update(iterator hint, const json_object& source) + void merge_or_update(iterator hint, const sorted_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { @@ -1165,7 +865,7 @@ namespace jsoncons { } } - void merge_or_update(iterator hint, json_object&& source) + void merge_or_update(iterator hint, sorted_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); @@ -1175,12 +875,12 @@ namespace jsoncons { if (hint != members_.end() && hint->key() <= (*it).key()) { pos = std::lower_bound(hint,members_.end(), (*it).key(), - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } else { pos = std::lower_bound(members_.begin(),members_.end(), (*it).key(), - [](const key_value_type& a, const string_view_type& k) -> bool {return string_view_type(a.key()).compare(k) < 0;}); + Comp()); } if (pos == members_.end() ) { @@ -1195,28 +895,36 @@ namespace jsoncons { } } - bool operator==(const json_object& rhs) const + bool operator==(const sorted_json_object& rhs) const { return members_ == rhs.members_; } - bool operator<(const json_object& rhs) const + bool operator<(const sorted_json_object& rhs) const { return members_ < rhs.members_; } private: - void destroy() noexcept + void flatten_and_destroy() noexcept { if (!members_.empty()) { json_array temp(get_allocator()); - for (auto&& kv : members_) + for (auto& kv : members_) { - if (kv.value().size() > 0) + switch (kv.value().storage_kind()) { - temp.emplace_back(std::move(kv.value())); + case json_storage_kind::array_value: + case json_storage_kind::object_value: + if (!kv.value().empty()) + { + temp.emplace_back(std::move(kv.value())); + } + break; + default: + break; } } } @@ -1224,9 +932,8 @@ namespace jsoncons { }; // Preserve order - template - class json_object::value>::type> : - public allocator_holder + template class SequenceContainer = std::vector> + class order_preserving_json_object : public allocator_holder { public: using allocator_type = typename Json::allocator_type; @@ -1235,53 +942,68 @@ namespace jsoncons { //using mapped_type = Json; using string_view_type = typename Json::string_view_type; using key_value_type = key_value; - using implementation_policy = typename Json::implementation_policy; + //using implementation_policy = typename Json::implementation_policy; private: + using key_value_allocator_type = typename std::allocator_traits:: template rebind_alloc; - using key_value_container_type = typename implementation_policy::template sequence_container_type; + using key_value_container_type = SequenceContainer; typedef typename std::allocator_traits:: template rebind_alloc index_allocator_type; - using index_container_type = typename implementation_policy::template sequence_container_type; + //using index_container_type = typename implementation_policy::template sequence_container_type; + using index_container_type = SequenceContainer; key_value_container_type members_; index_container_type index_; + + struct Comp + { + const key_value_container_type& members_; + + Comp(const key_value_container_type& members_) + : members_(members_) + { + } + + bool operator() (std::size_t i, string_view_type k) const { return members_.at(i).key() < k; } + bool operator() (string_view_type k, std::size_t i) const { return k < members_.at(i).key(); } + }; public: using iterator = typename key_value_container_type::iterator; using const_iterator = typename key_value_container_type::const_iterator; using allocator_holder::get_allocator; - json_object() + order_preserving_json_object() { } - json_object(const allocator_type& alloc) + order_preserving_json_object(const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)), index_(index_allocator_type(alloc)) { } - json_object(const json_object& val) + order_preserving_json_object(const order_preserving_json_object& val) : allocator_holder(val.get_allocator()), members_(val.members_), index_(val.index_) { } - json_object(json_object&& val) + order_preserving_json_object(order_preserving_json_object&& val) : allocator_holder(val.get_allocator()), members_(std::move(val.members_)), index_(std::move(val.index_)) { } - json_object(const json_object& val, const allocator_type& alloc) + order_preserving_json_object(const order_preserving_json_object& val, const allocator_type& alloc) : allocator_holder(alloc), members_(val.members_,key_value_allocator_type(alloc)), index_(val.index_,index_allocator_type(alloc)) { } - json_object(json_object&& val,const allocator_type& alloc) + order_preserving_json_object(order_preserving_json_object&& val,const allocator_type& alloc) : allocator_holder(alloc), members_(std::move(val.members_),key_value_allocator_type(alloc)), index_(std::move(val.index_),index_allocator_type(alloc)) @@ -1289,7 +1011,7 @@ namespace jsoncons { } template - json_object(InputIt first, InputIt last) + order_preserving_json_object(InputIt first, InputIt last) { std::size_t count = std::distance(first,last); members_.reserve(count); @@ -1324,7 +1046,7 @@ namespace jsoncons { } template - json_object(InputIt first, InputIt last, + order_preserving_json_object(InputIt first, InputIt last, const allocator_type& alloc) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)), @@ -1362,7 +1084,7 @@ namespace jsoncons { build_index(); } - json_object(std::initializer_list,Json>> init, + order_preserving_json_object(std::initializer_list,Json>> init, const allocator_type& alloc = allocator_type()) : allocator_holder(alloc), members_(key_value_allocator_type(alloc)), @@ -1375,18 +1097,18 @@ namespace jsoncons { } } - ~json_object() noexcept + ~order_preserving_json_object() noexcept { - destroy(); + flatten_and_destroy(); } - json_object& operator=(json_object&& val) + order_preserving_json_object& operator=(order_preserving_json_object&& val) { val.swap(*this); return *this; } - json_object& operator=(const json_object& val) + order_preserving_json_object& operator=(const order_preserving_json_object& val) { allocator_holder::operator=(val.get_allocator()); members_ = val.members_; @@ -1394,7 +1116,7 @@ namespace jsoncons { return *this; } - void swap(json_object& val) noexcept + void swap(order_preserving_json_object& val) noexcept { members_.swap(val.members_); } @@ -1466,25 +1188,32 @@ namespace jsoncons { iterator find(const string_view_type& name) noexcept { - auto it = std::lower_bound(index_.begin(),index_.end(), name, - [&](std::size_t i, const string_view_type& k) -> bool {return string_view_type(members_.at(i).key()).compare(k) < 0;}); - if (it != index_.end() && members_.at(*it).key() == name) - { - return members_.begin() + *it; - } - else - { - return members_.end(); - } + auto p = std::equal_range(index_.begin(),index_.end(), name, + Comp(members_)); + return p.first == p.second ? members_.end() : members_.begin() + *p.first; } const_iterator find(const string_view_type& name) const noexcept { - auto it = std::lower_bound(index_.begin(),index_.end(), name, - [&](std::size_t i, const string_view_type& k) -> bool {return string_view_type(members_.at(i).key()).compare(k) < 0;}); - if (it != index_.end() && members_.at(*it).key() == name) + auto p = std::equal_range(index_.begin(),index_.end(), name, + Comp(members_)); + return p.first == p.second ? members_.end() : members_.begin() + *p.first; + } + + iterator erase(const_iterator pos) + { + if (pos != members_.end()) { - return members_.begin() + *it; + std::size_t pos1 = pos - members_.begin(); + std::size_t pos2 = pos1 + 1; + + erase_index_entries(pos1, pos2); + #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) + iterator it = members_.begin() + (pos - members_.begin()); + return members_.erase(it); + #else + return members_.erase(pos); + #endif } else { @@ -1492,7 +1221,7 @@ namespace jsoncons { } } - void erase(const_iterator first, const_iterator last) + iterator erase(const_iterator first, const_iterator last) { std::size_t pos1 = first == members_.end() ? members_.size() : first - members_.begin(); std::size_t pos2 = last == members_.end() ? members_.size() : last - members_.begin(); @@ -1504,11 +1233,14 @@ namespace jsoncons { #if defined(JSONCONS_NO_ERASE_TAKING_CONST_ITERATOR) iterator it1 = members_.begin() + (first - members_.begin()); iterator it2 = members_.begin() + (last - members_.begin()); - members_.erase(it1,it2); + return members_.erase(it1,it2); #else - members_.erase(first,last); + return members_.erase(first,last); #endif - //build_index(); + } + else + { + return members_.end(); } } @@ -1678,7 +1410,7 @@ namespace jsoncons { // merge - void merge(const json_object& source) + void merge(const order_preserving_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { @@ -1686,7 +1418,7 @@ namespace jsoncons { } } - void merge(json_object&& source) + void merge(order_preserving_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); @@ -1700,7 +1432,7 @@ namespace jsoncons { } } - void merge(iterator hint, const json_object& source) + void merge(iterator hint, const order_preserving_json_object& source) { std::size_t pos = hint - members_.begin(); for (auto it = source.begin(); it != source.end(); ++it) @@ -1719,7 +1451,7 @@ namespace jsoncons { } } - void merge(iterator hint, json_object&& source) + void merge(iterator hint, order_preserving_json_object&& source) { std::size_t pos = hint - members_.begin(); @@ -1743,7 +1475,7 @@ namespace jsoncons { // merge_or_update - void merge_or_update(const json_object& source) + void merge_or_update(const order_preserving_json_object& source) { for (auto it = source.begin(); it != source.end(); ++it) { @@ -1751,7 +1483,7 @@ namespace jsoncons { } } - void merge_or_update(json_object&& source) + void merge_or_update(order_preserving_json_object&& source) { auto it = std::make_move_iterator(source.begin()); auto end = std::make_move_iterator(source.end()); @@ -1769,7 +1501,7 @@ namespace jsoncons { } } - void merge_or_update(iterator hint, const json_object& source) + void merge_or_update(iterator hint, const order_preserving_json_object& source) { std::size_t pos = hint - members_.begin(); for (auto it = source.begin(); it != source.end(); ++it) @@ -1788,7 +1520,7 @@ namespace jsoncons { } } - void merge_or_update(iterator hint, json_object&& source) + void merge_or_update(iterator hint, order_preserving_json_object&& source) { std::size_t pos = hint - members_.begin(); auto it = std::make_move_iterator(source.begin()); @@ -1904,18 +1636,18 @@ namespace jsoncons { } } - bool operator==(const json_object& rhs) const + bool operator==(const order_preserving_json_object& rhs) const { return members_ == rhs.members_; } - bool operator<(const json_object& rhs) const + bool operator<(const order_preserving_json_object& rhs) const { return members_ < rhs.members_; } private: - void destroy() noexcept + void flatten_and_destroy() noexcept { if (!members_.empty()) { @@ -1936,7 +1668,7 @@ namespace jsoncons { JSONCONS_ASSERT(pos <= index_.size()); auto it = std::lower_bound(index_.begin(),index_.end(), key, - [&](std::size_t i, const string_view_type& k) -> bool {return string_view_type(members_.at(i).key()).compare(k) < 0;}); + Comp(members_)); if (it == index_.end()) { @@ -1981,14 +1713,10 @@ namespace jsoncons { const size_t n = index_.size() - offset; for (std::size_t i = 0; i < index_.size(); ++i) { - if (offset == index_.size()) - { - index_.erase(index_.begin()+i,index_.end()); - i += offset; - } - else if (index_[i] >= pos1 && index_[i] < pos2) + if (index_[i] >= pos1 && index_[i] < pos2) { index_.erase(index_.begin()+i); + --i; } } for (std::size_t i = 0; i < index_.size(); ++i) diff --git a/module/lib/jsoncons/json_traits_macros.hpp b/module/lib/jsoncons/json_traits_macros.hpp index ffa1711d..321d8898 100644 --- a/module/lib/jsoncons/json_traits_macros.hpp +++ b/module/lib/jsoncons/json_traits_macros.hpp @@ -102,9 +102,9 @@ namespace jsoncons // Inspired by https://github.com/Loki-Astari/ThorsSerializer/blob/master/src/Serialize/Traits.h -#define JSONCONS_NARGS(...) JSONCONS_NARG_(__VA_ARGS__, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define JSONCONS_NARGS(...) JSONCONS_NARG_(__VA_ARGS__, 70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) #define JSONCONS_NARG_(...) JSONCONS_EXPAND( JSONCONS_ARG_N(__VA_ARGS__) ) -#define JSONCONS_ARG_N(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, N, ...) N +#define JSONCONS_ARG_N(e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31,e32,e33,e34,e35,e36,e37,e38,e39,e40,e41,e42,e43,e44,e45,e46,e47,e48,e49,e50,e51,e52,e53,e54,e55,e56,e57,e58,e59,e60,e61,e62,e63,e64,e65,e66,e67,e68,e69,e70,N,...)N #define JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, Count) Call(P1, P2, P3, P4, Count) @@ -112,10 +112,30 @@ namespace jsoncons #define JSONCONS_VARIADIC_REP_OF_N(Call, P1, P2, P3, Count, ...) JSONCONS_VARIADIC_REP_OF_N_(Call, P1, P2, P3, Count, __VA_ARGS__) #define JSONCONS_VARIADIC_REP_OF_N_(Call, P1, P2, P3, Count, ...) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_ ## Count(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_70(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 70) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_69(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_69(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 69) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_68(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_68(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 68) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_67(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_67(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 67) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_66(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_66(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 66) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_65(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_65(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 65) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_64(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_64(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 64) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_63(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_63(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 63) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_62(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_62(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 62) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_61(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_61(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 61) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_60(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_60(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 60) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_59(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_59(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 59) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_58(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_58(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 58) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_57(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_57(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 57) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_56(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_56(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 56) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_55(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_55(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 55) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_54(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_54(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 54) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_53(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_53(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 53) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_52(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_52(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 52) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_51(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_51(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 51) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_50(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_50(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 50) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_49(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_49(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 49) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_48(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_48(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 48) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_47(Call, P1, P2, P3, __VA_ARGS__)) -#define JSONCONS_VARIADIC_REP_OF_47(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 47, ) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_46(Call, P1, P2, P3, __VA_ARGS__)) +#define JSONCONS_VARIADIC_REP_OF_47(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 47) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_46(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_46(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 46) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_45(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_45(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 45) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_44(Call, P1, P2, P3, __VA_ARGS__)) #define JSONCONS_VARIADIC_REP_OF_44(Call, P1, P2, P3, P4, ...) JSONCONS_EXPAND_CALL5(Call, P1, P2, P3, P4, 44) JSONCONS_EXPAND(JSONCONS_VARIADIC_REP_OF_43(Call, P1, P2, P3, __VA_ARGS__)) @@ -327,7 +347,7 @@ namespace jsoncons \ #define JSONCONS_MEMBER_NAME_IS_4(Member, Name, Mode, Match) JSONCONS_MEMBER_NAME_IS_6(Member, Name, Mode, Match, , ) #define JSONCONS_MEMBER_NAME_IS_5(Member, Name, Mode, Match, Into) JSONCONS_MEMBER_NAME_IS_6(Member, Name, Mode, Match, Into, ) #define JSONCONS_MEMBER_NAME_IS_6(Member, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \ - JSONCONS_TRY{if (!Match(ajson.at(Name).template asMember))>::type>())) return false;} \ + JSONCONS_TRY{if (!Match(ajson.at(Name).template as())->Member))>::type>())) return false;} \ JSONCONS_CATCH(...) {return false;} #define JSONCONS_N_MEMBER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_N_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) @@ -338,9 +358,9 @@ namespace jsoncons \ #define JSONCONS_N_MEMBER_NAME_AS_4(Member, Name, Mode, Match) \ Mode(if (ajson.contains(Name)) {json_traits_helper::set_udt_member(ajson,Name,aval.Member);}) #define JSONCONS_N_MEMBER_NAME_AS_5(Member, Name, Mode, Match, Into) \ - Mode(if (ajson.contains(Name)) {json_traits_helper::template set_udt_memberMember))>::type>(ajson,Name,aval.Member);}) + Mode(if (ajson.contains(Name)) {json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,aval.Member);}) #define JSONCONS_N_MEMBER_NAME_AS_6(Member, Name, Mode, Match, Into, From) \ - Mode(if (ajson.contains(Name)) {json_traits_helper::template set_udt_memberMember))>::type>(ajson,Name,From,aval.Member);}) + Mode(if (ajson.contains(Name)) {json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,From,aval.Member);}) #define JSONCONS_ALL_MEMBER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_ALL_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_ALL_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_ALL_MEMBER_NAME_AS_,JSONCONS_NARGS Seq) Seq) @@ -350,9 +370,9 @@ namespace jsoncons \ #define JSONCONS_ALL_MEMBER_NAME_AS_4(Member, Name, Mode, Match) \ Mode(json_traits_helper::set_udt_member(ajson,Name,aval.Member);) #define JSONCONS_ALL_MEMBER_NAME_AS_5(Member, Name, Mode, Match, Into) \ - Mode(json_traits_helper::template set_udt_memberMember))>::type>(ajson,Name,aval.Member);) + Mode(json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,aval.Member);) #define JSONCONS_ALL_MEMBER_NAME_AS_6(Member, Name, Mode, Match, Into, From) \ - Mode(json_traits_helper::template set_udt_memberMember))>::type>(ajson,Name,From,aval.Member);) + Mode(json_traits_helper::template set_udt_member())->Member))>::type>(ajson,Name,From,aval.Member);) #define JSONCONS_N_MEMBER_NAME_TO_JSON(P1, P2, P3, Seq, Count) JSONCONS_N_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_N_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params2) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_N_MEMBER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq) @@ -437,7 +457,7 @@ namespace jsoncons \ #define JSONCONS_CTOR_GETTER_IS_LAST(Prefix, P2, P3, Getter, Count) if ((num_params-Count) < num_mandatory_params1 && !ajson.contains(json_traits_macro_names::Getter##_str(char_type{}))) return false; #define JSONCONS_CTOR_GETTER_AS(Prefix, P2, P3, Getter, Count) JSONCONS_CTOR_GETTER_AS_LAST(Prefix, P2, P3, Getter, Count), -#define JSONCONS_CTOR_GETTER_AS_LAST(Prefix, P2, P3, Getter, Count) ((num_params-Count) < num_mandatory_params2) ? (ajson.at(json_traits_macro_names::Getter##_str(char_type{}))).template asGetter())>::type>() : (ajson.contains(json_traits_macro_names::Getter##_str(char_type{})) ? (ajson.at(json_traits_macro_names::Getter##_str(char_type{}))).template asGetter())>::type>() : typename std::decayGetter())>::type()) +#define JSONCONS_CTOR_GETTER_AS_LAST(Prefix, P2, P3, Getter, Count) ((num_params-Count) < num_mandatory_params2) ? (ajson.at(json_traits_macro_names::Getter##_str(char_type{}))).template as())->Getter())>::type>() : (ajson.contains(json_traits_macro_names::Getter##_str(char_type{})) ? (ajson.at(json_traits_macro_names::Getter##_str(char_type{}))).template as())->Getter())>::type>() : typename std::decay())->Getter())>::type()) #define JSONCONS_CTOR_GETTER_TO_JSON(Prefix, P2, P3, Getter, Count) JSONCONS_CTOR_GETTER_TO_JSON_LAST(Prefix, P2, P3, Getter, Count) @@ -515,7 +535,7 @@ namespace jsoncons \ #define JSONCONS_CTOR_GETTER_NAME_IS_4(Getter, Name, Mode, Match) JSONCONS_CTOR_GETTER_NAME_IS_6(Getter, Name, Mode, Match, , ) #define JSONCONS_CTOR_GETTER_NAME_IS_5(Getter, Name, Mode, Match, Into) JSONCONS_CTOR_GETTER_NAME_IS_6(Getter, Name, Mode, Match, Into, ) #define JSONCONS_CTOR_GETTER_NAME_IS_6(Getter, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \ - JSONCONS_TRY{if (!Match(ajson.at(Name).template asGetter()))>::type>())) return false;} \ + JSONCONS_TRY{if (!Match(ajson.at(Name).template as())->Getter()))>::type>())) return false;} \ JSONCONS_CATCH(...) {return false;} #define JSONCONS_CTOR_GETTER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_CTOR_GETTER_NAME_AS_,JSONCONS_NARGS Seq) Seq) @@ -527,11 +547,11 @@ namespace jsoncons \ #define JSONCONS_COMMA , #define JSONCONS_CTOR_GETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_CTOR_GETTER_NAME_AS_LAST_,JSONCONS_NARGS Seq) Seq) -#define JSONCONS_CTOR_GETTER_NAME_AS_LAST_2(Getter, Name) (ajson.contains(Name)) ? (ajson.at(Name)).template asGetter())>::type>() : typename std::decayGetter())>::type() +#define JSONCONS_CTOR_GETTER_NAME_AS_LAST_2(Getter, Name) (ajson.contains(Name)) ? (ajson.at(Name)).template as())->Getter())>::type>() : typename std::decay())->Getter())>::type() #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_3(Getter, Name, Mode) Mode(JSONCONS_CTOR_GETTER_NAME_AS_LAST_2(Getter, Name)) #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_4(Getter, Name, Mode, Match) JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter, Name, Mode, Match,,) #define JSONCONS_CTOR_GETTER_NAME_AS_LAST_5(Getter, Name, Mode, Match, Into) JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter, Name, Mode, Match, Into, ) -#define JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter, Name, Mode, Match, Into, From) Mode(ajson.contains(Name) ? From(ajson.at(Name).template asGetter()))>::type>()) : From(typename std::decayGetter()))>::type())) +#define JSONCONS_CTOR_GETTER_NAME_AS_LAST_6(Getter, Name, Mode, Match, Into, From) Mode(ajson.contains(Name) ? From(ajson.at(Name).template as())->Getter()))>::type>()) : From(typename std::decay())->Getter()))>::type())) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON(P1, P2, P3, Seq, Count) JSONCONS_CTOR_GETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) #define JSONCONS_CTOR_GETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params2) JSONCONS_EXPAND(JSONCONS_CONCAT(JSONCONS_CTOR_GETTER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq) @@ -896,7 +916,7 @@ namespace jsoncons \ #define JSONCONS_GETTER_SETTER_NAME_IS_5(Getter, Setter, Name, Mode, Match) JSONCONS_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match,, ) #define JSONCONS_GETTER_SETTER_NAME_IS_6(Getter, Setter, Name, Mode, Match, Into) JSONCONS_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match, Into, ) #define JSONCONS_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \ - JSONCONS_TRY{if (!Match(ajson.at(Name).template asGetter()))>::type>())) return false;} \ + JSONCONS_TRY{if (!Match(ajson.at(Name).template as())->Getter()))>::type>())) return false;} \ JSONCONS_CATCH(...) {return false;} #define JSONCONS_N_GETTER_SETTER_NAME_AS(P1, P2, P3, Seq, Count) JSONCONS_N_GETTER_SETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) diff --git a/module/lib/jsoncons/json_type.hpp b/module/lib/jsoncons/json_type.hpp index d0f3970b..f642d6be 100644 --- a/module/lib/jsoncons/json_type.hpp +++ b/module/lib/jsoncons/json_type.hpp @@ -29,16 +29,16 @@ namespace jsoncons { template std::basic_ostream& operator<<(std::basic_ostream& os, json_type type) { - JSONCONS_CSTRING(CharT,null_value,'n','u','l','l') - JSONCONS_CSTRING(CharT,bool_value,'b','o','o','l') - JSONCONS_CSTRING(CharT,int64_value,'i','n','t','6','4') - JSONCONS_CSTRING(CharT,uint64_value,'u','i','n','t','6','4') - JSONCONS_CSTRING(CharT,half_value,'h','a','l','f') - JSONCONS_CSTRING(CharT,double_value,'d','o','u','b','l','e') - JSONCONS_CSTRING(CharT,string_value,'s','t','r','i','n','g') - JSONCONS_CSTRING(CharT,byte_string_value,'b','y','t','e',' ','s','t','r','i','n','g') - JSONCONS_CSTRING(CharT,array_value,'a','r','r','a','y') - JSONCONS_CSTRING(CharT,object_value,'o','b','j','e','c','t') + static constexpr const CharT* null_value = JSONCONS_CSTRING_CONSTANT(CharT, "null"); + static constexpr const CharT* bool_value = JSONCONS_CSTRING_CONSTANT(CharT, "bool"); + static constexpr const CharT* int64_value = JSONCONS_CSTRING_CONSTANT(CharT, "int64"); + static constexpr const CharT* uint64_value = JSONCONS_CSTRING_CONSTANT(CharT, "uint64"); + static constexpr const CharT* half_value = JSONCONS_CSTRING_CONSTANT(CharT, "half"); + static constexpr const CharT* double_value = JSONCONS_CSTRING_CONSTANT(CharT, "double"); + static constexpr const CharT* string_value = JSONCONS_CSTRING_CONSTANT(CharT, "string"); + static constexpr const CharT* byte_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string"); + static constexpr const CharT* array_value = JSONCONS_CSTRING_CONSTANT(CharT, "array"); + static constexpr const CharT* object_value = JSONCONS_CSTRING_CONSTANT(CharT, "object"); switch (type) { @@ -96,7 +96,7 @@ namespace jsoncons { return os; } - enum class storage_kind : uint8_t + enum class json_storage_kind : uint8_t { null_value = 0x00, bool_value = 0x01, @@ -114,85 +114,85 @@ namespace jsoncons { }; template - std::basic_ostream& operator<<(std::basic_ostream& os, storage_kind storage) + std::basic_ostream& operator<<(std::basic_ostream& os, json_storage_kind storage) { - JSONCONS_CSTRING(CharT,null_value,'n','u','l','l') - JSONCONS_CSTRING(CharT,bool_value,'b','o','o','l') - JSONCONS_CSTRING(CharT,int64_value,'i','n','t','6','4') - JSONCONS_CSTRING(CharT,uint64_value,'u','i','n','t','6','4') - JSONCONS_CSTRING(CharT,half_value,'h','a','l','f') - JSONCONS_CSTRING(CharT,double_value,'d','o','u','b','l','e') - JSONCONS_CSTRING(CharT,short_string_value,'s','h','o','r','t',' ','s','t','r','i','n','g') - JSONCONS_CSTRING(CharT,long_string_value,'l','o','n','g',' ','s','t','r','i','n','g') - JSONCONS_CSTRING(CharT,byte_string_value,'b','y','t','e',' ','s','t','r','i','n','g') - JSONCONS_CSTRING(CharT,array_value,'a','r','r','a','y') - JSONCONS_CSTRING(CharT,empty_object_value,'e','m','p','t','y',' ','o','b','j','e','c','t') - JSONCONS_CSTRING(CharT,object_value,'o','b','j','e','c','t') - JSONCONS_CSTRING(CharT,json_const_pointer,'j','s','o','n',' ','c','o','n','s','t',' ','p','o','i','n','t','e','r') + static constexpr const CharT* null_value = JSONCONS_CSTRING_CONSTANT(CharT, "null"); + static constexpr const CharT* bool_value = JSONCONS_CSTRING_CONSTANT(CharT, "bool"); + static constexpr const CharT* int64_value = JSONCONS_CSTRING_CONSTANT(CharT, "int64"); + static constexpr const CharT* uint64_value = JSONCONS_CSTRING_CONSTANT(CharT, "uint64"); + static constexpr const CharT* half_value = JSONCONS_CSTRING_CONSTANT(CharT, "half"); + static constexpr const CharT* double_value = JSONCONS_CSTRING_CONSTANT(CharT, "double"); + static constexpr const CharT* short_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "short_string"); + static constexpr const CharT* long_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "string"); + static constexpr const CharT* byte_string_value = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string"); + static constexpr const CharT* array_value = JSONCONS_CSTRING_CONSTANT(CharT, "array"); + static constexpr const CharT* empty_object_value = JSONCONS_CSTRING_CONSTANT(CharT, "empty_object"); + static constexpr const CharT* object_value = JSONCONS_CSTRING_CONSTANT(CharT, "object"); + static constexpr const CharT* json_const_pointer = JSONCONS_CSTRING_CONSTANT(CharT, "json_const_pointer"); switch (storage) { - case storage_kind::null_value: + case json_storage_kind::null_value: { os << null_value; break; } - case storage_kind::bool_value: + case json_storage_kind::bool_value: { os << bool_value; break; } - case storage_kind::int64_value: + case json_storage_kind::int64_value: { os << int64_value; break; } - case storage_kind::uint64_value: + case json_storage_kind::uint64_value: { os << uint64_value; break; } - case storage_kind::half_value: + case json_storage_kind::half_value: { os << half_value; break; } - case storage_kind::double_value: + case json_storage_kind::double_value: { os << double_value; break; } - case storage_kind::short_string_value: + case json_storage_kind::short_string_value: { os << short_string_value; break; } - case storage_kind::long_string_value: + case json_storage_kind::long_string_value: { os << long_string_value; break; } - case storage_kind::byte_string_value: + case json_storage_kind::byte_string_value: { os << byte_string_value; break; } - case storage_kind::array_value: + case json_storage_kind::array_value: { os << array_value; break; } - case storage_kind::empty_object_value: + case json_storage_kind::empty_object_value: { os << empty_object_value; break; } - case storage_kind::object_value: + case json_storage_kind::object_value: { os << object_value; break; } - case storage_kind::json_const_pointer: + case json_storage_kind::json_const_pointer: { os << json_const_pointer; break; diff --git a/module/lib/jsoncons/json_visitor2.hpp b/module/lib/jsoncons/json_visitor2.hpp index d6d261bf..7477070e 100644 --- a/module/lib/jsoncons/json_visitor2.hpp +++ b/module/lib/jsoncons/json_visitor2.hpp @@ -810,9 +810,9 @@ namespace jsoncons { string_type key_buffer_; std::vector level_stack_; - const std::basic_string null_k = {'n','u','l','l'}; - const std::basic_string true_k = { 't','r','u','e' }; - const std::basic_string false_k = { 'f', 'a', 'l', 's', 'e' }; + const std::basic_string null_constant = {'n','u','l','l'}; + const std::basic_string true_constant = { 't','r','u','e' }; + const std::basic_string false_constant = { 'f', 'a', 'l', 's', 'e' }; // noncopyable and nonmoveable basic_json_visitor2_to_visitor_adaptor(const basic_json_visitor2_to_visitor_adaptor&) = delete; @@ -1417,7 +1417,7 @@ namespace jsoncons { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { - key_ = value ? true_k : false_k; + key_ = value ? true_constant : false_constant; } if (level_stack_.back().is_key()) @@ -1466,7 +1466,7 @@ namespace jsoncons { if (level_stack_.back().is_key() || level_stack_.back().target() == target_t::buffer) { - key_ = null_k; + key_ = null_constant; } if (level_stack_.back().is_key()) diff --git a/module/lib/jsoncons/staj_cursor.hpp b/module/lib/jsoncons/staj_cursor.hpp index 1c66811f..c665360d 100644 --- a/module/lib/jsoncons/staj_cursor.hpp +++ b/module/lib/jsoncons/staj_cursor.hpp @@ -50,19 +50,19 @@ enum class staj_event_type template std::basic_ostream& operator<<(std::basic_ostream& os, staj_event_type tag) { - JSONCONS_CSTRING(CharT,begin_array_name,'b','e','g','i','n','_','a','r','r','a','y') - JSONCONS_CSTRING(CharT,end_array_name,'e','n','d','_','a','r','r','a','y') - JSONCONS_CSTRING(CharT,begin_object_name,'b','e','g','i','n','_','o','b','j','e','c','t') - JSONCONS_CSTRING(CharT,end_object_name,'e','n','d','_','o','b','j','e','c','t') - JSONCONS_CSTRING(CharT,key_name,'k','e','y') - JSONCONS_CSTRING(CharT,string_value_name,'s','t','r','i','n','g','_','v','a','l','u','e') - JSONCONS_CSTRING(CharT,byte_string_value_name,'b','y','t','e','_','s','t','r','i','n','g','_','v','a','l','u','e') - JSONCONS_CSTRING(CharT,null_value_name,'n','u','l','l','_','v','a','l','u','e') - JSONCONS_CSTRING(CharT,bool_value_name,'b','o','o','l','_','v','a','l','u','e') - JSONCONS_CSTRING(CharT,uint64_value_name,'u','i','n','t','6','4','_','v','a','l','u','e') - JSONCONS_CSTRING(CharT,int64_value_name,'i','n','t','6','4','_','v','a','l','u','e') - JSONCONS_CSTRING(CharT,half_value_name,'h','a','l','f','_','v','a','l','u','e') - JSONCONS_CSTRING(CharT,double_value_name,'d','o','u','b','l','e','_','v','a','l','u','e') + static constexpr const CharT* begin_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_array"); + static constexpr const CharT* end_array_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_array"); + static constexpr const CharT* begin_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "begin_object"); + static constexpr const CharT* end_object_name = JSONCONS_CSTRING_CONSTANT(CharT, "end_object"); + static constexpr const CharT* key_name = JSONCONS_CSTRING_CONSTANT(CharT, "key"); + static constexpr const CharT* string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "string_value"); + static constexpr const CharT* byte_string_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "byte_string_value"); + static constexpr const CharT* null_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "null_value"); + static constexpr const CharT* bool_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "bool_value"); + static constexpr const CharT* uint64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "uint64_value"); + static constexpr const CharT* int64_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "int64_value"); + static constexpr const CharT* half_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "half_value"); + static constexpr const CharT* double_value_name = JSONCONS_CSTRING_CONSTANT(CharT, "double_value"); switch (tag) { diff --git a/module/lib/jsoncons/tag_type.hpp b/module/lib/jsoncons/tag_type.hpp index 87ae4268..ffefd8a6 100644 --- a/module/lib/jsoncons/tag_type.hpp +++ b/module/lib/jsoncons/tag_type.hpp @@ -101,27 +101,27 @@ enum class semantic_tag : uint8_t template std::basic_ostream& operator<<(std::basic_ostream& os, semantic_tag tag) { - JSONCONS_CSTRING(CharT,na_name,'n','/','a') - JSONCONS_CSTRING(CharT,undefined_name,'u','n','d','e','f','i','n','e','d') - JSONCONS_CSTRING(CharT,datetime_name,'d','a','t','e','t','i','m','e') - JSONCONS_CSTRING(CharT,epoch_second_name,'e','p','o','c','h','-','s','e','c','o','n','d') - JSONCONS_CSTRING(CharT,epoch_milli_name,'e','p','o','c','h','-','m','i','l','l','i') - JSONCONS_CSTRING(CharT,epoch_nano_name,'e','p','o','c','h','-','n','a','n','o') - JSONCONS_CSTRING(CharT,bigint_name,'b','i','g','i','n','t') - JSONCONS_CSTRING(CharT,bigdec_name,'b','i','g','d','e','c') - JSONCONS_CSTRING(CharT,bigfloat_name,'b','i','g','f','l','o','a','t') - JSONCONS_CSTRING(CharT,base16_name,'b','a','s','e','l','6') - JSONCONS_CSTRING(CharT,base64_name,'b','a','s','e','6','4') - JSONCONS_CSTRING(CharT,base64url_name,'b','a','s','e','6','4','u','r','l') - JSONCONS_CSTRING(CharT,uri_name,'u','r','i') - JSONCONS_CSTRING(CharT,clamped_name,'c','l','a','m','p','e','d') - JSONCONS_CSTRING(CharT,multi_dim_row_major_name,'m','u','l','t','i','-','d','i','m','-','r','o','w','-','m','a','j','o','r') - JSONCONS_CSTRING(CharT,multi_dim_column_major_name,'m','u','l','t','i','-','d','i','m','-','c','o','l','u','m','n','-','m','a','j','o','r') - JSONCONS_CSTRING(CharT,ext_name,'e','x','t') - JSONCONS_CSTRING(CharT,id_name,'i','d') - JSONCONS_CSTRING(CharT, float128_name, 'f', 'l', 'o', 'a', 't', '1', '2', '8') - JSONCONS_CSTRING(CharT, regex_name, 'r', 'e', 'g', 'e', 'x') - JSONCONS_CSTRING(CharT, code_name, 'c', 'o', 'd', 'e') + static constexpr const CharT* na_name = JSONCONS_CSTRING_CONSTANT(CharT, "n/a"); + static constexpr const CharT* undefined_name = JSONCONS_CSTRING_CONSTANT(CharT, "undefined"); + static constexpr const CharT* datetime_name = JSONCONS_CSTRING_CONSTANT(CharT, "datetime"); + static constexpr const CharT* epoch_second_name = JSONCONS_CSTRING_CONSTANT(CharT, "epoch-second"); + static constexpr const CharT* epoch_milli_name = JSONCONS_CSTRING_CONSTANT(CharT, "epoch-milli"); + static constexpr const CharT* epoch_nano_name = JSONCONS_CSTRING_CONSTANT(CharT, "epoch-nano"); + static constexpr const CharT* bigint_name = JSONCONS_CSTRING_CONSTANT(CharT, "bigint"); + static constexpr const CharT* bigdec_name = JSONCONS_CSTRING_CONSTANT(CharT, "bigdec"); + static constexpr const CharT* bigfloat_name = JSONCONS_CSTRING_CONSTANT(CharT, "bigfloat"); + static constexpr const CharT* base16_name = JSONCONS_CSTRING_CONSTANT(CharT, "base16"); + static constexpr const CharT* base64_name = JSONCONS_CSTRING_CONSTANT(CharT, "base64"); + static constexpr const CharT* base64url_name = JSONCONS_CSTRING_CONSTANT(CharT, "base64url"); + static constexpr const CharT* uri_name = JSONCONS_CSTRING_CONSTANT(CharT, "uri"); + static constexpr const CharT* clamped_name = JSONCONS_CSTRING_CONSTANT(CharT, "clamped"); + static constexpr const CharT* multi_dim_row_major_name = JSONCONS_CSTRING_CONSTANT(CharT, "multi-dim-row-major"); + static constexpr const CharT* multi_dim_column_major_name = JSONCONS_CSTRING_CONSTANT(CharT, "multi-dim-column-major"); + static constexpr const CharT* ext_name = JSONCONS_CSTRING_CONSTANT(CharT, "ext"); + static constexpr const CharT* id_name = JSONCONS_CSTRING_CONSTANT(CharT, "id"); + static constexpr const CharT* float128_name = JSONCONS_CSTRING_CONSTANT(CharT, "float128"); + static constexpr const CharT* regex_name = JSONCONS_CSTRING_CONSTANT(CharT, "regex"); + static constexpr const CharT* code_name = JSONCONS_CSTRING_CONSTANT(CharT, "code"); switch (tag) { diff --git a/module/lib/pybind11/attr.h b/module/lib/pybind11/attr.h index f1b66fb8..de95f89d 100644 --- a/module/lib/pybind11/attr.h +++ b/module/lib/pybind11/attr.h @@ -20,54 +20,62 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// @{ /// Annotation for methods -struct is_method { handle class_; +struct is_method { + handle class_; explicit is_method(const handle &c) : class_(c) {} }; /// Annotation for operators -struct is_operator { }; +struct is_operator {}; /// Annotation for classes that cannot be subclassed -struct is_final { }; +struct is_final {}; /// Annotation for parent scope -struct scope { handle value; +struct scope { + handle value; explicit scope(const handle &s) : value(s) {} }; /// Annotation for documentation -struct doc { const char *value; +struct doc { + const char *value; explicit doc(const char *value) : value(value) {} }; /// Annotation for function names -struct name { const char *value; +struct name { + const char *value; explicit name(const char *value) : value(value) {} }; /// Annotation indicating that a function is an overload associated with a given "sibling" -struct sibling { handle value; +struct sibling { + handle value; explicit sibling(const handle &value) : value(value.ptr()) {} }; /// Annotation indicating that a class derives from another given type -template struct base { +template +struct base { - PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") - base() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute + PYBIND11_DEPRECATED( + "base() was deprecated in favor of specifying 'T' as a template argument to class_") + base() {} // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute }; /// Keep patient alive while nurse lives -template struct keep_alive { }; +template +struct keep_alive {}; /// Annotation indicating that a class is involved in a multiple inheritance relationship -struct multiple_inheritance { }; +struct multiple_inheritance {}; /// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class -struct dynamic_attr { }; +struct dynamic_attr {}; /// Annotation which enables the buffer protocol for a type -struct buffer_protocol { }; +struct buffer_protocol {}; /// Annotation which requests that a special metaclass is created for a type struct metaclass { @@ -78,7 +86,7 @@ struct metaclass { metaclass() {} /// Override pybind11's default metaclass - explicit metaclass(handle value) : value(value) { } + explicit metaclass(handle value) : value(value) {} }; /// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that @@ -99,15 +107,16 @@ struct custom_type_setup { }; /// Annotation that marks a class as local to the module: -struct module_local { const bool value; +struct module_local { + const bool value; constexpr explicit module_local(bool v = true) : value(v) {} }; /// Annotation to mark enums as an arithmetic type -struct arithmetic { }; +struct arithmetic {}; /// Mark a function for addition at the beginning of the existing overload chain instead of the end -struct prepend { }; +struct prepend {}; /** \rst A call policy which places one or more guard variables (``Ts...``) around the function call. @@ -127,9 +136,13 @@ struct prepend { }; return foo(args...); // forwarded arguments }); \endrst */ -template struct call_guard; +template +struct call_guard; -template <> struct call_guard<> { using type = detail::void_type; }; +template <> +struct call_guard<> { + using type = detail::void_type; +}; template struct call_guard { @@ -154,7 +167,8 @@ PYBIND11_NAMESPACE_BEGIN(detail) enum op_id : int; enum op_type : int; struct undefined_t; -template struct op_; +template +struct op_; void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); /// Internal data structure which holds metadata about a keyword argument @@ -166,15 +180,16 @@ struct argument_record { bool none : 1; ///< True if None is allowed when loading argument_record(const char *name, const char *descr, handle value, bool convert, bool none) - : name(name), descr(descr), value(value), convert(convert), none(none) { } + : name(name), descr(descr), value(value), convert(convert), none(none) {} }; -/// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) +/// Internal data structure which holds metadata about a bound function (signature, overloads, +/// etc.) struct function_record { function_record() : is_constructor(false), is_new_style_constructor(false), is_stateless(false), - is_operator(false), is_method(false), has_args(false), - has_kwargs(false), prepend(false) { } + is_operator(false), is_method(false), has_args(false), has_kwargs(false), + prepend(false) {} /// Function name char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ @@ -189,13 +204,13 @@ struct function_record { std::vector args; /// Pointer to lambda function which converts arguments and performs the actual call - handle (*impl) (function_call &) = nullptr; + handle (*impl)(function_call &) = nullptr; /// Storage for the wrapped function pointer and captured data, if any - void *data[3] = { }; + void *data[3] = {}; /// Pointer to custom destructor for 'data' (if needed) - void (*free_data) (function_record *ptr) = nullptr; + void (*free_data)(function_record *ptr) = nullptr; /// Return value policy associated with this function return_value_policy policy = return_value_policy::automatic; @@ -251,7 +266,7 @@ struct function_record { struct type_record { PYBIND11_NOINLINE type_record() : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), - default_holder(true), module_local(false), is_final(false) { } + default_holder(true), module_local(false), is_final(false) {} /// Handle to the parent scope handle scope; @@ -310,42 +325,43 @@ struct type_record { /// Is the class inheritable from python classes? bool is_final : 1; - PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { - auto base_info = detail::get_type_info(base, false); + PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) { + auto *base_info = detail::get_type_info(base, false); if (!base_info) { std::string tname(base.name()); detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + - "\" referenced unknown base type \"" + tname + "\""); + pybind11_fail("generic_type: type \"" + std::string(name) + + "\" referenced unknown base type \"" + tname + "\""); } if (default_holder != base_info->default_holder) { std::string tname(base.name()); detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + - (default_holder ? "does not have" : "has") + - " a non-default holder type while its base \"" + tname + "\" " + - (base_info->default_holder ? "does not" : "does")); + pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + + (default_holder ? "does not have" : "has") + + " a non-default holder type while its base \"" + tname + "\" " + + (base_info->default_holder ? "does not" : "does")); } bases.append((PyObject *) base_info->type); - if (base_info->type->tp_dictoffset != 0) + if (base_info->type->tp_dictoffset != 0) { dynamic_attr = true; + } - if (caster) + if (caster) { base_info->implicit_casts.emplace_back(type, caster); + } } }; -inline function_call::function_call(const function_record &f, handle p) : - func(f), parent(p) { +inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) { args.reserve(f.nargs); args_convert.reserve(f.nargs); } /// Tag for a new-style `__init__` defined in `detail/init.h` -struct is_new_style_constructor { }; +struct is_new_style_constructor {}; /** * Partial template specializations to process custom attributes provided to @@ -353,74 +369,97 @@ struct is_new_style_constructor { }; * fields in the type_record and function_record data structures or executed at * runtime to deal with custom call policies (e.g. keep_alive). */ -template struct process_attribute; +template +struct process_attribute; -template struct process_attribute_default { +template +struct process_attribute_default { /// Default implementation: do nothing - static void init(const T &, function_record *) { } - static void init(const T &, type_record *) { } - static void precall(function_call &) { } - static void postcall(function_call &, handle) { } + static void init(const T &, function_record *) {} + static void init(const T &, type_record *) {} + static void precall(function_call &) {} + static void postcall(function_call &, handle) {} }; /// Process an attribute specifying the function's name -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } }; /// Process an attribute specifying the function's docstring -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } }; /// Process an attribute specifying the function's docstring (provided as a C-style string) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const char *d, function_record *r) { r->doc = const_cast(d); } static void init(const char *d, type_record *r) { r->doc = const_cast(d); } }; -template <> struct process_attribute : process_attribute { }; +template <> +struct process_attribute : process_attribute {}; /// Process an attribute indicating the function's return value policy -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const return_value_policy &p, function_record *r) { r->policy = p; } }; -/// Process an attribute which indicates that this is an overloaded function associated with a given sibling -template <> struct process_attribute : process_attribute_default { +/// Process an attribute which indicates that this is an overloaded function associated with a +/// given sibling +template <> +struct process_attribute : process_attribute_default { static void init(const sibling &s, function_record *r) { r->sibling = s.value; } }; /// Process an attribute which indicates that this function is a method -template <> struct process_attribute : process_attribute_default { - static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } +template <> +struct process_attribute : process_attribute_default { + static void init(const is_method &s, function_record *r) { + r->is_method = true; + r->scope = s.class_; + } }; /// Process an attribute which indicates the parent scope of a method -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const scope &s, function_record *r) { r->scope = s.value; } }; /// Process an attribute which indicates that this function is an operator -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const is_operator &, function_record *r) { r->is_operator = true; } }; -template <> struct process_attribute : process_attribute_default { - static void init(const is_new_style_constructor &, function_record *r) { r->is_new_style_constructor = true; } +template <> +struct process_attribute + : process_attribute_default { + static void init(const is_new_style_constructor &, function_record *r) { + r->is_new_style_constructor = true; + } }; inline void check_kw_only_arg(const arg &a, function_record *r) { - if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) - pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or args() argument"); + if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) { + pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or " + "args() argument"); + } } inline void append_self_arg_if_needed(function_record *r) { - if (r->is_method && r->args.empty()) - r->args.emplace_back("self", nullptr, handle(), /*convert=*/ true, /*none=*/ false); + if (r->is_method && r->args.empty()) { + r->args.emplace_back("self", nullptr, handle(), /*convert=*/true, /*none=*/false); + } } /// Process a keyword argument attribute (*without* a default value) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const arg &a, function_record *r) { append_self_arg_if_needed(r); r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); @@ -430,26 +469,33 @@ template <> struct process_attribute : process_attribute_default { }; /// Process a keyword argument attribute (*with* a default value) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const arg_v &a, function_record *r) { - if (r->is_method && r->args.empty()) - r->args.emplace_back("self", /*descr=*/ nullptr, /*parent=*/ handle(), /*convert=*/ true, /*none=*/ false); + if (r->is_method && r->args.empty()) { + r->args.emplace_back( + "self", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false); + } if (!a.value) { #if !defined(NDEBUG) std::string descr("'"); - if (a.name) descr += std::string(a.name) + ": "; + if (a.name) { + descr += std::string(a.name) + ": "; + } descr += a.type + "'"; if (r->is_method) { - if (r->name) - descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; - else + if (r->name) { + descr += " in method '" + (std::string) str(r->scope) + "." + + (std::string) r->name + "'"; + } else { descr += " in method of '" + (std::string) str(r->scope) + "'"; + } } else if (r->name) { descr += " in function '" + (std::string) r->name + "'"; } - pybind11_fail("arg(): could not convert default argument " - + descr + " into a Python object (type not registered yet?)"); + pybind11_fail("arg(): could not convert default argument " + descr + + " into a Python object (type not registered yet?)"); #else pybind11_fail("arg(): could not convert default argument " "into a Python object (type not registered yet?). " @@ -463,29 +509,36 @@ template <> struct process_attribute : process_attribute_default { }; /// Process a keyword-only-arguments-follow pseudo argument -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const kw_only &, function_record *r) { append_self_arg_if_needed(r); - if (r->has_args && r->nargs_pos != static_cast(r->args.size())) - pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative argument location (or omit kw_only() entirely)"); + if (r->has_args && r->nargs_pos != static_cast(r->args.size())) { + pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative " + "argument location (or omit kw_only() entirely)"); + } r->nargs_pos = static_cast(r->args.size()); } }; /// Process a positional-only-argument maker -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const pos_only &, function_record *r) { append_self_arg_if_needed(r); r->nargs_pos_only = static_cast(r->args.size()); - if (r->nargs_pos_only > r->nargs_pos) + if (r->nargs_pos_only > r->nargs_pos) { pybind11_fail("pos_only(): cannot follow a py::args() argument"); - // It also can't follow a kw_only, but a static_assert in pybind11.h checks that + } + // It also can't follow a kw_only, but a static_assert in pybind11.h checks that } }; -/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that) +/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees +/// that) template -struct process_attribute::value>> : process_attribute_default { +struct process_attribute::value>> + : process_attribute_default { static void init(const handle &h, type_record *r) { r->bases.append(h); } }; @@ -498,7 +551,9 @@ struct process_attribute> : process_attribute_default> { /// Process a multiple inheritance attribute template <> struct process_attribute : process_attribute_default { - static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } + static void init(const multiple_inheritance &, type_record *r) { + r->multiple_inheritance = true; + } }; template <> @@ -544,34 +599,41 @@ template <> struct process_attribute : process_attribute_default {}; template -struct process_attribute> : process_attribute_default> { }; +struct process_attribute> : process_attribute_default> {}; /** * Process a keep_alive call policy -- invokes keep_alive_impl during the * pre-call handler if both Nurse, Patient != 0 and use the post-call handler * otherwise */ -template struct process_attribute> : public process_attribute_default> { +template +struct process_attribute> + : public process_attribute_default> { template = 0> - static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); } + static void precall(function_call &call) { + keep_alive_impl(Nurse, Patient, call, handle()); + } template = 0> - static void postcall(function_call &, handle) { } + static void postcall(function_call &, handle) {} template = 0> - static void precall(function_call &) { } + static void precall(function_call &) {} template = 0> - static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); } + static void postcall(function_call &call, handle ret) { + keep_alive_impl(Nurse, Patient, call, ret); + } }; /// Recursively iterate over variadic template arguments -template struct process_attributes { - static void init(const Args&... args, function_record *r) { +template +struct process_attributes { + static void init(const Args &...args, function_record *r) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r); PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r); using expander = int[]; (void) expander{ 0, ((void) process_attribute::type>::init(args, r), 0)...}; } - static void init(const Args&... args, type_record *r) { + static void init(const Args &...args, type_record *r) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r); PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r); using expander = int[]; @@ -603,7 +665,7 @@ using extract_guard_t = typename exactly_one_t, Extr /// Check the number of named arguments at compile time template ::value...), - size_t self = constexpr_sum(std::is_same::value...)> + size_t self = constexpr_sum(std::is_same::value...)> constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs); return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs; diff --git a/module/lib/pybind11/buffer_info.h b/module/lib/pybind11/buffer_info.h index eba68d1a..06120d55 100644 --- a/module/lib/pybind11/buffer_info.h +++ b/module/lib/pybind11/buffer_info.h @@ -19,9 +19,11 @@ PYBIND11_NAMESPACE_BEGIN(detail) inline std::vector c_strides(const std::vector &shape, ssize_t itemsize) { auto ndim = shape.size(); std::vector strides(ndim, itemsize); - if (ndim > 0) - for (size_t i = ndim - 1; i > 0; --i) + if (ndim > 0) { + for (size_t i = ndim - 1; i > 0; --i) { strides[i - 1] = strides[i] * shape[i]; + } + } return strides; } @@ -29,8 +31,9 @@ inline std::vector c_strides(const std::vector &shape, ssize_t inline std::vector f_strides(const std::vector &shape, ssize_t itemsize) { auto ndim = shape.size(); std::vector strides(ndim, itemsize); - for (size_t i = 1; i < ndim; ++i) + for (size_t i = 1; i < ndim; ++i) { strides[i] = strides[i - 1] * shape[i - 1]; + } return strides; } @@ -41,55 +44,85 @@ struct buffer_info { void *ptr = nullptr; // Pointer to the underlying storage ssize_t itemsize = 0; // Size of individual items in bytes ssize_t size = 0; // Total number of entries - std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() + std::string format; // For homogeneous buffers, this should be set to + // format_descriptor::format() ssize_t ndim = 0; // Number of dimensions std::vector shape; // Shape of the tensor (1 entry per dimension) - std::vector strides; // Number of bytes between adjacent entries (for each per dimension) + std::vector strides; // Number of bytes between adjacent entries + // (for each per dimension) bool readonly = false; // flag to indicate if the underlying storage may be written to buffer_info() = default; - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container shape_in, detail::any_container strides_in, bool readonly=false) - : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), - shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { - if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), + shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { + if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) { pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); - for (size_t i = 0; i < (size_t) ndim; ++i) + } + for (size_t i = 0; i < (size_t) ndim; ++i) { size *= shape[i]; + } } template - buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in, bool readonly=false) - : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in), readonly) { } - - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size, bool readonly=false) - : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) { } + buffer_info(T *ptr, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : buffer_info(private_ctr_tag(), + ptr, + sizeof(T), + format_descriptor::format(), + static_cast(shape_in->size()), + std::move(shape_in), + std::move(strides_in), + readonly) {} + + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t size, + bool readonly = false) + : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {} template - buffer_info(T *ptr, ssize_t size, bool readonly=false) - : buffer_info(ptr, sizeof(T), format_descriptor::format(), size, readonly) { } + buffer_info(T *ptr, ssize_t size, bool readonly = false) + : buffer_info(ptr, sizeof(T), format_descriptor::format(), size, readonly) {} template - buffer_info(const T *ptr, ssize_t size, bool readonly=true) - : buffer_info(const_cast(ptr), sizeof(T), format_descriptor::format(), size, readonly) { } + buffer_info(const T *ptr, ssize_t size, bool readonly = true) + : buffer_info( + const_cast(ptr), sizeof(T), format_descriptor::format(), size, readonly) {} explicit buffer_info(Py_buffer *view, bool ownview = true) - : buffer_info(view->buf, view->itemsize, view->format, view->ndim, + : buffer_info( + view->buf, + view->itemsize, + view->format, + view->ndim, {view->shape, view->shape + view->ndim}, /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects * ignore this flag and return a view with NULL strides. * When strides are NULL, build them manually. */ view->strides - ? std::vector(view->strides, view->strides + view->ndim) - : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), + ? std::vector(view->strides, view->strides + view->ndim) + : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), (view->readonly != 0)) { + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer) this->m_view = view; + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer) this->ownview = ownview; } buffer_info(const buffer_info &) = delete; - buffer_info& operator=(const buffer_info &) = delete; + buffer_info &operator=(const buffer_info &) = delete; buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); } @@ -108,17 +141,28 @@ struct buffer_info { } ~buffer_info() { - if (m_view && ownview) { PyBuffer_Release(m_view); delete m_view; } + if (m_view && ownview) { + PyBuffer_Release(m_view); + delete m_view; + } } Py_buffer *view() const { return m_view; } Py_buffer *&view() { return m_view; } -private: - struct private_ctr_tag { }; - buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container &&shape_in, detail::any_container &&strides_in, bool readonly) - : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) { } +private: + struct private_ctr_tag {}; + + buffer_info(private_ctr_tag, + void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container &&shape_in, + detail::any_container &&strides_in, + bool readonly) + : buffer_info( + ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {} Py_buffer *m_view = nullptr; bool ownview = false; @@ -126,17 +170,22 @@ struct buffer_info { PYBIND11_NAMESPACE_BEGIN(detail) -template struct compare_buffer_info { - static bool compare(const buffer_info& b) { +template +struct compare_buffer_info { + static bool compare(const buffer_info &b) { return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); } }; -template struct compare_buffer_info::value>> { - static bool compare(const buffer_info& b) { - return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || - ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || - ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); +template +struct compare_buffer_info::value>> { + static bool compare(const buffer_info &b) { + return (size_t) b.itemsize == sizeof(T) + && (b.format == format_descriptor::value + || ((sizeof(T) == sizeof(long)) + && b.format == (std::is_unsigned::value ? "L" : "l")) + || ((sizeof(T) == sizeof(size_t)) + && b.format == (std::is_unsigned::value ? "N" : "n"))); } }; diff --git a/module/lib/pybind11/cast.h b/module/lib/pybind11/cast.h index 7930fb99..5b7fb24f 100644 --- a/module/lib/pybind11/cast.h +++ b/module/lib/pybind11/cast.h @@ -10,11 +10,12 @@ #pragma once -#include "pytypes.h" #include "detail/common.h" #include "detail/descr.h" #include "detail/type_caster_base.h" #include "detail/typeid.h" +#include "pytypes.h" + #include #include #include @@ -30,41 +31,51 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) -template class type_caster : public type_caster_base { }; -template using make_caster = type_caster>; +template +class type_caster : public type_caster_base {}; +template +using make_caster = type_caster>; // Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T -template typename make_caster::template cast_op_type cast_op(make_caster &caster) { +template +typename make_caster::template cast_op_type cast_op(make_caster &caster) { return caster.operator typename make_caster::template cast_op_type(); } -template typename make_caster::template cast_op_type::type> +template +typename make_caster::template cast_op_type::type> cast_op(make_caster &&caster) { - return std::move(caster).operator - typename make_caster::template cast_op_type::type>(); + return std::move(caster).operator typename make_caster:: + template cast_op_type::type>(); } -template class type_caster> { +template +class type_caster> { private: using caster_t = make_caster; caster_t subcaster; - using reference_t = type&; - using subcaster_cast_op_type = - typename caster_t::template cast_op_type; - - static_assert(std::is_same::type &, subcaster_cast_op_type>::value || - std::is_same::value, - "std::reference_wrapper caster requires T to have a caster with an " - "`operator T &()` or `operator const T &()`"); + using reference_t = type &; + using subcaster_cast_op_type = typename caster_t::template cast_op_type; + + static_assert( + std::is_same::type &, subcaster_cast_op_type>::value + || std::is_same::value, + "std::reference_wrapper caster requires T to have a caster with an " + "`operator T &()` or `operator const T &()`"); + public: bool load(handle src, bool convert) { return subcaster.load(src, convert); } static constexpr auto name = caster_t::name; - static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { + static handle + cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { // It is definitely wrong to take ownership of this pointer, so mask that rvp - if (policy == return_value_policy::take_ownership || policy == return_value_policy::automatic) + if (policy == return_value_policy::take_ownership + || policy == return_value_policy::automatic) { policy = return_value_policy::automatic_reference; + } return caster_t::cast(&src.get(), policy, parent); } - template using cast_op_type = std::reference_wrapper; + template + using cast_op_type = std::reference_wrapper; explicit operator std::reference_wrapper() { return cast_op(subcaster); } }; @@ -74,11 +85,15 @@ protected: \ public: \ static constexpr auto name = py_name; \ - template >::value, int> = 0> \ - static handle cast(T_ *src, return_value_policy policy, handle parent) { \ + template >::value, \ + int> = 0> \ + static ::pybind11::handle cast( \ + T_ *src, ::pybind11::return_value_policy policy, ::pybind11::handle parent) { \ if (!src) \ - return none().release(); \ - if (policy == return_value_policy::take_ownership) { \ + return ::pybind11::none().release(); \ + if (policy == ::pybind11::return_value_policy::take_ownership) { \ auto h = cast(std::move(*src), policy, parent); \ delete src; \ return h; \ @@ -89,31 +104,33 @@ public: operator type &() { return value; } /* NOLINT(bugprone-macro-parentheses) */ \ operator type &&() && { return std::move(value); } /* NOLINT(bugprone-macro-parentheses) */ \ template \ - using cast_op_type = pybind11::detail::movable_cast_op_type + using cast_op_type = ::pybind11::detail::movable_cast_op_type -template using is_std_char_type = any_of< - std::is_same, /* std::string */ +template +using is_std_char_type = any_of, /* std::string */ #if defined(PYBIND11_HAS_U8STRING) - std::is_same, /* std::u8string */ + std::is_same, /* std::u8string */ #endif - std::is_same, /* std::u16string */ - std::is_same, /* std::u32string */ - std::is_same /* std::wstring */ ->; - + std::is_same, /* std::u16string */ + std::is_same, /* std::u32string */ + std::is_same /* std::wstring */ + >; template struct type_caster::value && !is_std_char_type::value>> { using _py_type_0 = conditional_t; - using _py_type_1 = conditional_t::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>; + using _py_type_1 = conditional_t::value, + _py_type_0, + typename std::make_unsigned<_py_type_0>::type>; using py_type = conditional_t::value, double, _py_type_1>; -public: +public: bool load(handle src, bool convert) { py_type py_value; - if (!src) + if (!src) { return false; + } #if !defined(PYPY_VERSION) auto index_check = [](PyObject *o) { return PyIndex_Check(o); }; @@ -124,10 +141,11 @@ struct type_caster::value && !is_std_char_t #endif if (std::is_floating_point::value) { - if (convert || PyFloat_Check(src.ptr())) + if (convert || PyFloat_Check(src.ptr())) { py_value = (py_type) PyFloat_AsDouble(src.ptr()); - else + } else { return false; + } } else if (PyFloat_Check(src.ptr()) || (!convert && !PYBIND11_LONG_CHECK(src.ptr()) && !index_check(src.ptr()))) { return false; @@ -136,14 +154,13 @@ struct type_caster::value && !is_std_char_t // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls. #if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION) object index; - if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) + if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) index = reinterpret_steal(PyNumber_Index(src.ptr())); if (!index) { PyErr_Clear(); if (!convert) return false; - } - else { + } else { src_or_index = index; } } @@ -152,8 +169,8 @@ struct type_caster::value && !is_std_char_t py_value = as_unsigned(src_or_index.ptr()); } else { // signed integer: py_value = sizeof(T) <= sizeof(long) - ? (py_type) PyLong_AsLong(src_or_index.ptr()) - : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr()); + ? (py_type) PyLong_AsLong(src_or_index.ptr()) + : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr()); } } @@ -162,12 +179,14 @@ struct type_caster::value && !is_std_char_t // Check to see if the conversion is valid (integers should match exactly) // Signed/unsigned checks happen elsewhere - if (py_err || (std::is_integral::value && sizeof(py_type) != sizeof(T) && py_value != (py_type) (T) py_value)) { + if (py_err + || (std::is_integral::value && sizeof(py_type) != sizeof(T) + && py_value != (py_type) (T) py_value)) { PyErr_Clear(); if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) { auto tmp = reinterpret_steal(std::is_floating_point::value - ? PyNumber_Float(src.ptr()) - : PyNumber_Long(src.ptr())); + ? PyNumber_Float(src.ptr()) + : PyNumber_Long(src.ptr())); PyErr_Clear(); return load(tmp, false); } @@ -178,32 +197,40 @@ struct type_caster::value && !is_std_char_t return true; } - template + template static typename std::enable_if::value, handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyFloat_FromDouble((double) src); } - template - static typename std::enable_if::value && std::is_signed::value && (sizeof(U) <= sizeof(long)), handle>::type + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) <= sizeof(long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PYBIND11_LONG_FROM_SIGNED((long) src); } - template - static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) <= sizeof(unsigned long)), handle>::type + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) <= sizeof(unsigned long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src); } - template - static typename std::enable_if::value && std::is_signed::value && (sizeof(U) > sizeof(long)), handle>::type + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) > sizeof(long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyLong_FromLongLong((long long) src); } - template - static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) > sizeof(unsigned long)), handle>::type + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) > sizeof(unsigned long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyLong_FromUnsignedLongLong((unsigned long long) src); } @@ -211,11 +238,13 @@ struct type_caster::value && !is_std_char_t PYBIND11_TYPE_CASTER(T, const_name::value>("int", "float")); }; -template struct void_caster { +template +struct void_caster { public: bool load(handle src, bool) { - if (src && src.is_none()) + if (src && src.is_none()) { return true; + } return false; } static handle cast(T, return_value_policy /* policy */, handle /* parent */) { @@ -224,9 +253,11 @@ template struct void_caster { PYBIND11_TYPE_CASTER(T, const_name("None")); }; -template <> class type_caster : public void_caster {}; +template <> +class type_caster : public void_caster {}; -template <> class type_caster : public type_caster { +template <> +class type_caster : public type_caster { public: using type_caster::cast; @@ -246,7 +277,7 @@ template <> class type_caster : public type_caster { } /* Check if this is a C++ type */ - auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr()); + const auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr()); if (bases.size() == 1) { // Only allowing loading from a single-value type value = values_and_holders(reinterpret_cast(h.ptr())).begin()->value_ptr(); return true; @@ -257,24 +288,31 @@ template <> class type_caster : public type_caster { } static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) { - if (ptr) + if (ptr) { return capsule(ptr).release(); + } return none().inc_ref(); } - template using cast_op_type = void*&; + template + using cast_op_type = void *&; explicit operator void *&() { return value; } static constexpr auto name = const_name("capsule"); + private: void *value = nullptr; }; -template <> class type_caster : public void_caster { }; +template <> +class type_caster : public void_caster {}; -template <> class type_caster { +template <> +class type_caster { public: bool load(handle src, bool convert) { - if (!src) return false; + if (!src) { + return false; + } if (src.ptr() == Py_True) { value = true; return true; @@ -288,22 +326,22 @@ template <> class type_caster { Py_ssize_t res = -1; if (src.is_none()) { - res = 0; // None is implicitly converted to False + res = 0; // None is implicitly converted to False } - #if defined(PYPY_VERSION) +#if defined(PYPY_VERSION) // On PyPy, check that "__bool__" (or "__nonzero__" on Python 2.7) attr exists else if (hasattr(src, PYBIND11_BOOL_ATTR)) { res = PyObject_IsTrue(src.ptr()); } - #else +#else // Alternate approach for CPython: this does the same as the above, but optimized // using the CPython API so as to avoid an unneeded attribute lookup. - else if (auto tp_as_number = src.ptr()->ob_type->tp_as_number) { + else if (auto *tp_as_number = src.ptr()->ob_type->tp_as_number) { if (PYBIND11_NB_BOOL(tp_as_number)) { res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr()); } } - #endif +#endif if (res == 0 || res == 1) { value = (res != 0); return true; @@ -319,20 +357,25 @@ template <> class type_caster { }; // Helper class for UTF-{8,16,32} C++ stl strings: -template struct string_caster { +template +struct string_caster { using CharT = typename StringType::value_type; // Simplify life by being able to assume standard char sizes (the standard only guarantees // minimums, but Python requires exact sizes) - static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char size != 1"); + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char size != 1"); #if defined(PYBIND11_HAS_U8STRING) - static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char8_t size != 1"); + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char8_t size != 1"); #endif - static_assert(!std::is_same::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2"); - static_assert(!std::is_same::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4"); + static_assert(!std::is_same::value || sizeof(CharT) == 2, + "Unsupported char16_t size != 2"); + static_assert(!std::is_same::value || sizeof(CharT) == 4, + "Unsupported char32_t size != 4"); // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) static_assert(!std::is_same::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, - "Unsupported wchar_t size != 2/4"); + "Unsupported wchar_t size != 2/4"); static constexpr size_t UTF_N = 8 * sizeof(CharT); bool load(handle src, bool) { @@ -356,7 +399,10 @@ template struct string_caster { return false; temp = reinterpret_steal(PyUnicode_FromObject(load_src.ptr())); - if (!temp) { PyErr_Clear(); return false; } + if (!temp) { + PyErr_Clear(); + return false; + } load_src = temp; #endif } @@ -377,11 +423,19 @@ template struct string_caster { } #endif - auto utfNbytes = reinterpret_steal(PyUnicode_AsEncodedString( - load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); - if (!utfNbytes) { PyErr_Clear(); return false; } + auto utfNbytes + = reinterpret_steal(PyUnicode_AsEncodedString(load_src.ptr(), + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr)); + if (!utfNbytes) { + PyErr_Clear(); + return false; + } - const auto *buffer = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); + const auto *buffer + = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); // Skip BOM for UTF-16/32 if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) { @@ -391,17 +445,21 @@ template struct string_caster { value = StringType(buffer, length); // If we're loading a string_view we need to keep the encoded Python object alive: - if (IsView) + if (IsView) { loader_life_support::add_patient(utfNbytes); + } return true; } - static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { + static handle + cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { const char *buffer = reinterpret_cast(src.data()); auto nbytes = ssize_t(src.size() * sizeof(CharT)); handle s = decode_utfN(buffer, nbytes); - if (!s) throw error_already_set(); + if (!s) { + throw error_already_set(); + } return s; } @@ -410,14 +468,19 @@ template struct string_caster { private: static handle decode_utfN(const char *buffer, ssize_t nbytes) { #if !defined(PYPY_VERSION) - return - UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) : - UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) : - PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); + return UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) + : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) + : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); #else - // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as well), - // so bypass the whole thing by just passing the encoding as a string value, which works properly: - return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr); + // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as + // well), so bypass the whole thing by just passing the encoding as a string value, which + // works properly: + return PyUnicode_Decode(buffer, + nbytes, + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr); #endif } @@ -440,33 +503,43 @@ template struct string_caster { } template - bool load_bytes(enable_if_t::value, handle>) { return false; } + bool load_bytes(enable_if_t::value, handle>) { + return false; + } }; template -struct type_caster, enable_if_t::value>> +struct type_caster, + enable_if_t::value>> : string_caster> {}; #ifdef PYBIND11_HAS_STRING_VIEW template -struct type_caster, enable_if_t::value>> +struct type_caster, + enable_if_t::value>> : string_caster, true> {}; #endif // Type caster for C-style strings. We basically use a std::string type caster, but also add the // ability to use None as a nullptr char* (which the string caster doesn't allow). -template struct type_caster::value>> { +template +struct type_caster::value>> { using StringType = std::basic_string; using StringCaster = type_caster; StringCaster str_caster; bool none = false; CharT one_char = 0; + public: bool load(handle src, bool convert) { - if (!src) return false; + if (!src) { + return false; + } if (src.is_none()) { // Defer accepting None to other overloads (if we aren't in convert mode): - if (!convert) return false; + if (!convert) { + return false; + } none = true; return true; } @@ -474,14 +547,18 @@ template struct type_caster::value) { handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr); - if (!s) throw error_already_set(); + if (!s) { + throw error_already_set(); + } return s; } return StringCaster::cast(StringType(1, src), policy, parent); @@ -491,19 +568,21 @@ template struct type_caster(static_cast(str_caster).c_str()); } explicit operator CharT &() { - if (none) + if (none) { throw value_error("Cannot convert None to a character"); + } auto &value = static_cast(str_caster); size_t str_len = value.size(); - if (str_len == 0) + if (str_len == 0) { throw value_error("Cannot convert empty string to a character"); + } // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that - // is too high, and one for multiple unicode characters (caught later), so we need to figure - // out how long the first encoded character is in bytes to distinguish between these two - // errors. We also allow want to allow unicode characters U+0080 through U+00FF, as those - // can fit into a single char value. + // is too high, and one for multiple unicode characters (caught later), so we need to + // figure out how long the first encoded character is in bytes to distinguish between these + // two errors. We also allow want to allow unicode characters U+0080 through U+00FF, as + // those can fit into a single char value. if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) { auto v0 = static_cast(value[0]); // low bits only: 0-127 @@ -518,7 +597,8 @@ template struct type_caster(((v0 & 3) << 6) + (static_cast(value[1]) & 0x3F)); + one_char = static_cast(((v0 & 3) << 6) + + (static_cast(value[1]) & 0x3F)); return one_char; } // Otherwise we have a single character, but it's > U+00FF @@ -531,34 +611,40 @@ template struct type_caster(value[0]); - if (one_char >= 0xD800 && one_char < 0xE000) + if (one_char >= 0xD800 && one_char < 0xE000) { throw value_error("Character code point not in range(0x10000)"); + } } - if (str_len != 1) + if (str_len != 1) { throw value_error("Expected a character, but multi-character string found"); + } one_char = value[0]; return one_char; } static constexpr auto name = const_name(PYBIND11_STRING_NAME); - template using cast_op_type = pybind11::detail::cast_op_type<_T>; + template + using cast_op_type = pybind11::detail::cast_op_type<_T>; }; // Base implementation for std::tuple and std::pair -template class Tuple, typename... Ts> class tuple_caster { +template